Cloud Functions for Firebase — A Quick-start
Getting started with Firebase Cloud Functions with an use case
While developing mobile and web applications, we often require to carry out some backend operations with response to certain events taking place in our application. Let’s say we want to send a welcome message when a new user signs up on our platform. Traditionally this was done using a backend code running on our own server. This process was inefficient in many ways including managing the security, server maintenance and others.
The Cloud Functions for Firebase exactly allows us to achieve this (and much more). From the docs:
Cloud Functions for Firebase is a serverless framework that lets you automatically run backend code in response to events triggered by Firebase features and HTTPS requests.
It offers a number of advantages such as:
- Managing and scaling the servers
- Low maintenance
- Keeping the logic private and secure
In this article, we will take a simple use case which I went through in one of my projects, automatically assigning a delivery boy when a new order is added to the Cloud Firestore database using Cloud Firestore Triggers. We will write and deploy a cloud function for the same. So let’s get started!
Getting Started
1. Create a Firebase Project
To use Firebase services, we need to create a Firebase Project. To do so, head over to the Firebase console, click on Add project. Give your project a name, Click on Continue. Click on Create Project. This will take a while.
Once the project is created, select Cloud Firestore from the console, click on Create Database.
Start in test mode, click next, choose a location for your database and click on enable. Once it is done, we are ready to move to the next step.
2. Set up Firebase CLI
Before we start writing cloud functions, we need to have Firebase CLI installed on our system. We can install it with the following command:
npm install -g firebase-tools
For running the above command, you need to have Node.js installed on your machine. Run the same command to update the CLI.
3. Initialize the Project
To use the Firebase project created in the first step, we need to login to the firebase using the following command:
firebase login
This will generate an URL which you can visit using any browser to complete the login process.
Once the login is done, we need to initialize both firestore and functions in our project.
Initialize firestore using the following command:
firebase init firestore
Select Use an existing project, use arrow keys to select the project which we created in the first step.
Select the default values for the next steps and you should see the successful completion of the initialization process.
Let’s initialize the cloud functions now:
firebase init functions
We will be writing cloud functions in JavaScript, so select it using the arrow keys. We won’t be using ESlint, so choose No when asked. Choose Yes for installing dependencies with npm. The initialization will take a while to complete. Once it is done, you should see the following:
Once the initialization is complete, we will have the following directory structure:
We will only be writing code in the index.js
file inside the functions
directory. Time to get your hands dirty! :P
4. Database Structure
Before we move forward to the implementation part, let’s take a moment to understand the database structure in our Cloud Firestore
database.
Let’s consider we have two Collections
, orders
containing all the orders as they are placed and boys
containing all the delivery boys.
We can think of many possible fields for a order
and boy
but in this case we will only consider fields required for our example.
Some of the important fields in an order
can be:
- order ID (stored as
orderId
in database) - Destination coordinates (stored as
latLng
in database) status
for storing the order status (isPlaced
initially)
On successful execution of the cloud function, we expect the order
to have status
as Assigned
and have two more fields added to the document
namely the delivery boy ID (stored as boyID
) and delivery boy name (stored as boyName
)
With this in mind, let’s start implementing the cloud function.
5. Implementation
Open up index.js
in the functions folder. Let’s start by importing the required modules and initializing the app. We will require the firebase-functions
and firebase-admin
modules.
We will require the admin SDK
to access other parts of the database such as other documents
andcollections
in the database.
Next, we will be implementing the logic based on which the delivery boy will be assigned. For this example, I’ll be using Haversine Formula to calculate distance between the location coordinates of the order destination and delivery boy location. Without going into the math, I’ll be using the code snippet copied from Google blog.
Let’s now start writing the actual function. We want to trigger the cloud function every time a new document (a new order in this case) is added to the firestore. Thus, we will use onCreate
as the Event type. There are other event types as well which are shown below:
Let’s now start defining the function trigger:
We want to attach the onCreate
trigger to each document in the orders
collection. We achieve this by using a {wildcard}
in place of the document ID. In our example, when any new document is created in orders
, it will match the wildcard orderId
. The snap
is a QuerySnapShot
which can be used to access the current document.
The next step is to get the latLng
from the snapshot and check for the minimum distance between the location coordinates of the delivery boy and the order delivery location.
Here, we iterate through the boys
collection using the admin SDK which we imported earlier. We store the boy document that has the minimum distance from order destination in minBoy
variable and the actual distance in min
variable.
The next and the last step is to actually update the same order
document to assign the delivery boy to the order.
We access the name
of the delivery boy by using minBoy.data().name
as we stored the document reference in the minBoy
variable. The ref
is a special property which stores the reference of the document on which the function was invoked as aDocumentReference
. We update the document using update()
and return the result of the update as the result of the cloud function.
Here’s the complete code of index.js
:
5. Deploy the Function
The final step is to deploy the function we created to the production environment. To do this, run the following command:
firebase deploy --only functions
NOTE: Billing must be enabled to deploy the functions, else you will encounter errors.
Once it succeeds, you will see something like this:
That’s it! You have successfully deployed the function!
You can check the deployed function from the console. Here’s the screenshot:
You can also monitor the usage, health and logs from the console itself by switching to the required tabs.
Conclusion
Cloud Functions for Firebase provides a convenient way to run server side code in response to the events on your backend. In this article, we studied how we can use it with Cloud Firestore via a simple use case. We also saw how to deploy the function to the production environment.
The background functions can be triggered with other Firebase products as well such as Realtime database, authentication, analytics, remote config and cloud storage. Please let me know if you want an article on any of these :)