Flutter x Firebase | Cloud Functions

Jackie Moraa
5 min readFeb 17, 2024

--

In the previous article we added the main functionality for our application — users being able to submit cat photos to the database. We explored Firebase Extensions to shorten the image source URLs. Catch up on the article in case you missed it, as we’ll be building on the applications functionality in this article.

Today, we’ll be adding a nice-to-have feature — comments. Once a user submits a photo, we would like the other users (or themselves) to be able to leave comments on the image. While this feature will provide a ground for the users to interact and share their thoughts, the reality is that sometimes unmoderated comments descend into toxicity and bullying. Most applications with online comment sections have become battlegrounds among the users. Because we don’t want our wonderful application to have a hostile user comment section, we might need to “gate keep” these comments to ensure there is only healthy and productive discourse among the users. And we can easily moderate comments using Firebase Cloud Functions.

Cloud Functions for Firebase is a serverless framework that lets you automatically run backend code in response to events triggered by background events, HTTPS requests, the Admin SDK, or Cloud Scheduler jobs. Your JavaScript, TypeScript or Python code is stored on Google Cloud infrastructure and runs in a managed environment.

Cloud Functions allow you to extend the functionality of your Firebase app without managing your own servers or infrastructure.

Key capabilities of Cloud Functions

  • It is event-driven: Your code is automatically triggered by events. E.g., a new comment written to the DB, a new user being created etc. The functions you write can respond to events generated by various Firebase and Google Cloud features.
  • Easy to use: Deploy your JavaScript, TypeScript, or Python code to our servers with one command from the command line.
  • Scalable & maintenance: Firebase automatically scales up computing resources to match the usage patterns of your users. You never worry about credentials, server configuration, provisioning new servers, or decommissioning old ones.
  • Secure: Your code runs in a secure environment with built-in access control. It keeps your logic private and secure

Implementing comment moderation with Cloud Functions.

User interface
We’ll start by modifying our application for sending and displaying comments. In the screenshot below, I’ve added the comment button which when clicked will show the bottom modal sheet. It is in that sheet where a user can post a comment and see all the comments posted for that image.

I’ve added another Firestore collection called comments which will host all the comments posted and with this code snippet, we can successfully post comments to that DB.

Future _addComment({required String comment}) async {
DocumentReference docRef = await FirebaseFirestore.instance.collection('comments').add(
{
'comment': comment,
},
);
String commentId = docRef.id;
await FirebaseFirestore.instance.collection('comments').doc(commentId).update(
{'id': commentId},
);
}

Cloud functions initialisation
We already did the Firebase set up for our application but we’ll need to set up the Functions services. So, in your terminal type firebase init and using the space bar select Functions. Select the projects you want to initialise the functions and the language you would want to use to write the functions.

Once this runs, Firebase will generate a folder called functions at the root of your application with several files in it. You can write your cloud functions in the ‘functions/index.js’ or another .js file if you prefer (you’ll need to specify that file in the package.json however). Firebase Cloud Functions have a number of DB triggers, e.g., onCreate (when data is added in the DB), onUpdate (when DB data is changed), onDelete (when data is removed from the DB), etc.

Bad words
In order to moderate comments, you’ll need to have a repository of words that are not allowed. You can manually create the list of unacceptable words or phrases to use in your application. There are also Firebase Extensions that can be used in place of this. In our example however, we’ll be making use of the bad words package which is a JavaScript filter for “bad words”. Within the functions folder run: npm install bad-words@3.0.4

JavaScript function
Now in the .js file, write the logic to moderate the comments. When a message is posted in the comments collection, the onCreate method will be triggered. The comment will then be analysed for profanity based on the words filtered in the package. If the comment is deemed to not be safe, it will be marked with a moderated flag.

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const Filter = require("bad-words");
const filter = new Filter();


exports.moderateComments = functions.firestore.document("comments/{id}")
.onCreate(async (snapshot) => {
const text = snapshot.data();
const comment = text.comment;

// Moderation logic
const isSafe = !filter.isProfane(comment);

if (!isSafe) {
// If the comment is not safe, update it in Firestore
await snapshot.ref.update({moderated: true});
}
});

Deploy the function
To deploy the function, simply run: firebase deploy — only functions

You can now also see the function on your Firebase console.

Testing
Now let’s see whether our function works as expected.

From the demo above, you can see the difference in how the two comments were treated. In the first comment without profanity, the comment was not moderated, the flag remained false. However, in the second comment, the moderated flag was updated to true because the comment contained a word that was flagged as profanity.

Now using the flags, we can choose to only display the comments that do not have any swear words and profanities in our comments collection. This will ensure that our comment section remains holistic — after all, we are talking about cats and they can do no wrong!

fireStore.collection('comments').where('moderated', isEqualTo: false).snapshots(),

I experienced quite a number of challenges the first time I tried working with Firebase Cloud Functions sometime last year but I hope this article has simplified the process.

In our next February another article, we’ll be looking at yet another Firebase service. So buckle up for that!

“Don’t say anything online that you wouldn’t want plastered on a billboard with your face on it.”
— Erin Bury

Once again, thank you for reading! ❤

--

--