Firebase Functions Tutorial — Data Validation

A few months ago, I published an article (and video) covering how to build a REST API using Firebase Functions. Since then, I’ve gotten a lot of questions on how to implement more features such as authentication and data validation. In my last article, I covered authentication and in this article, we’re going to be talking about data validation.
When creating a REST API, authentication and data validation are critical to maintaining the integrity of your data. Authentication prohibits malicious people 😠 from sniffing API endpoints and manipulating or accessing data. Data validation prohibits authenticated and front end developers from sending malformed data to the backend/database.
Since this tutorial is going to build on a previous one, we’ll be using the code from it. If you’d like to follow along you can find it in this BitBucket Repo. So, clone the project and let's start coding 🙌!
Firebase Setup
In order to publish our functions, add users to our database, and use authentication, we’re going to have to set up a Firebase project. So, head over to https://firebase.google.com/ create an account and then click “Go to console”. Next, click on the “Add project” button and name it whatever you’d like. Click through the other options choosing the defaults.
Firestore
Next click on “Cloud Firestore” in the left-hand menu.

Then, at the top of the screen click “Create database”.

For now, choose Start in test mode and pick the default server location.

Warning: This will leave your database open for anyone to read and write to it. If you are going to use this in a production setting, PLEASE familiarize yourself with Firestore rules.
Firebase CLI
Firebase makes it pretty simple to install their boilerplate functions in our project. In my previous article, we signed up for Firebase and added the config to our project, but for functions, we’ll need to install the Firebase CLI globally on our computer. To do this, open your terminal and run the following command:
npm install -g firebase-tools
Now that we have it installed, we need to sync it to our account. Run the following in your command prompt and log in:
firebase login
Initializing Firebase in Cloned Project
To sync the cloned project (from the beginning) with your Firebase account, we’re going to need to delete some files. Go ahead and delete the following files out of the project:
- .firebaserc
- firebase.json
- firestore.rules
- firestore.indexes.json
Now, open a terminal at the root of the Firebase API project cloned in the beginning. Then run the following command:
firebase init
Provide these answers to the following questions:
- Are you ready to proceed? — Y
- Which Firebase CLI features do you want to set up for this folder? — Functions
- Please select an option: — Use an existing project
- Select the firebase project you set up earlier
- What language would you like to use to write Cloud Functions? — JavaScript
- Do you want to use ESLint to catch probable bugs and enforce style? — y
- File functions/package.json already exists. Overwrite? — n
- File functions/.eslintrc.json already exists. Overwrite? — n
- File functions/index.js already exists. Overwrite? — n
- File functions/.gitignore already exists. Overwrite? — n
- Do you want to install dependencies with npm now? — Y
Next, to make sure all previous dependencies are installed cd into the functions folder from the terminal and run the following command:
npm i
Firebase Functions Data Validation
Since our Firebase Functions utilize the Express Framework, we can tap into a large ecosystem of plugins. In particular, we’ll be using the express-validator. This makes it extremely easy to write validations for our endpoint.
To install express-validator, open a terminal in of the functions folder of the project, and run the following command:
npm install --save express-validator
User Creation
Since we only have one POST endpoint in our project, we’ll be focusing on that. You can see the code for it here:
app.post("/", async (req, res) => {
const user = req.body;
await admin.firestore().collection("users").add(user);
res.status(201).send();
});
Validation Rules
What we want to do is pass in a request body with the following properties and validations:
- email— Required and verify its a valid email
- firstName — Required
- lastName — Required
- age — Required and must be an integer
- password — Required and Min Length of 6 characters
- userType — Must be either “admin” or “customer”
- language — Optional, but if added must be either “javascript”, “python”, or “C#”
Express Validator Code
Now we can start coding out our validator. At the top of our index.js file, import what we’ll need for express-validator.
const { body, validationResult } = require('express-validator');
The best aspect of express-validator is all of the built-in validators. We’ll use the body property we imported earlier to chain validators. Then we’ll place them in an array to use on as middleware on our endpoint:
const userCreationValidators = [
body('email').isEmail(),
body('firstName').notEmpty(),
body('lastName').notEmpty(),
body('age').isInt(),
body('password').isLength({min: 5}),
body('userType').notEmpty().isIn(["admin", "customer"]),
body('language').optional().isIn(['javascript', "python", "C#"])
];
Now we just need to add our validations to our endpoint and use the validationResult method to verify our request body verse our validations:
app.post("/", userCreationValidators, async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const user = req.body;
await admin.firestore().collection("users").add(user);
res.status(201).send();
});
Testing
So now if I run the Firebase local emulator to test my function locally and hit the endpoint with Postman without a request body, we’ll see we get a status of 400 and a response body with all the errors. The major benefit of the errors is that it will help our front-end developers adjust their requests.

Custom Error Messages
As we can see from the error messages, “Invalid value” is not very descriptive. This can particularly cause issues when you work on a team with dedicated front and backend developers. Luckily express-validator gives us an extremely easy way to add custom error messages.
All you have to do is chain the withMessage method after your validator:
const userCreationValidators = [
body('email').isEmail().withMessage("Email is invalid!")
body('firstName').notEmpty().withMessage("First Name required!"),
body('lastName').notEmpty().withMessage("Last Name required!"),
body('age').isInt().withMessage("Age must be int!"),
body('password').isLength({min: 5}),
body('userType').notEmpty().isIn(["admin", "customer"]),
body('language').optional().isIn(['javascript', "python", "C#"])
];
Video Tutorial
Conclusion
As you can see data validation with Firebase Functions/Express is extremely easy with express-validator. This will ensure that your data integrity is protected and no malicious data will be injected into your database. I hope you found this tutorial helpful. If so, drop me line below. And, until next time, Happy Coding!