Background Trigger Functions
Explore how to create Cloud Functions that respond to background events in Firebase like user creation, database changes, and Firestore updates. Learn how to handle authentication triggers, monitor Realtime Database and Firestore events, and write functions that automate processes based on data changes. This lesson provides practical guidance on setting up triggers and managing event data for efficient app integrations.
We'll cover the following...
In the Introduction to Cloud Functions lesson, we mentioned that we can trigger Cloud Functions in response to events coming from Firebase products. These types of functions are called background trigger functions. Examples of such event triggers include the following:
- When a user signs up with Firebase authentication
- A write, update, or delete operation on the Realtime Database or Cloud Firestore
- A conversion event in Google Analytics
With the Cloud Functions for Firebase SDK, we can monitor these events and trigger a function in response to such events. This allows us to handle them the way we want to. Let’s take a look at some of these.
Note: All background trigger functions must be terminated by returning a promise that is fulfilled after the function completes all the work to be done. However, if there is no work, we can return
nullto terminate the function.
Authentication triggers
We can trigger Cloud Functions for Firebase in response to a user creation or a deletion event on our Firebase application. We do this by using either the onCreate or onDelete handlers with the functions.auth.user() function. These handlers take a callback function with a parameter, user. We use this parameter to access the user’s attributes, similar to the client SDK:
- Line 1: We call the
firebase-functionsmodule and assign it to a constant,functions. - Line 4: We export the
userSignupfunction. Thefunctions.auth.user().onCreatemethod indicates that this function will only respond to user creation events. - Lines 5 and 6: We access the
userobject to retrieve the user’s name and email, respectively. - Line 8: We log the function status along with the user’s
emailanduidto the Firebase console. -Line 13: We export theuserDeletefunction that responds to deletion events.
Realtime Database triggers
We can trigger Cloud Functions for Firebase in response to events in the Realtime Database. Cloud Functions wait for a change in a particular location on the database, as specified by the reference. They trigger when the specified event type occurs. Then, it receives a data object that contains a snapshot of the data after and, in some cases, before the trigger event.
We can create these functions using functions.database. Then, we must specify a path to the database location using the ref function. Then, we attach an event handler that triggers in response to specific event types. The Realtime Database supports four different event handlers:
-
onCreate: This triggers when new data is created on the Realtime Database. -
onDelete: This triggers when data is deleted from the Realtime Database. -
onUpdate: This triggers when a change is made to existing data in the Realtime Database. -
onWrite: This responds to create, update, and delete operations to the location in the Realtime Database.
- Line 1: We call the
firebase-functionsmodule required to run all Cloud Functions. - Line 4: We export our sample function, which is a database-triggered function.
- Line 5: We define a path on the database that triggers the function. Here, we set our path to
/users/educative/tasks. - Line 6: We call the
onCreatemethod and pass in thesnapshotandcontextparameters. Thesnapshotparameter contains a snapshot of the data stored in the location. Thecontextparameter contains additional information about the user and the triggered event. - Line 8: We access the
uidfrom thecontextobject and assign it to auidconstant. - Line 11: We terminate the function with the
returnstatement.
We can also use wildcards when defining the path reference. These allow us to match any child of the parent path in the location. We can access the values of the wildcard components under the context object as below:
Let’s go over the snippet above:
-
Line 5: We define a path on the database that triggers the function. Notice the use of the wildcard,
{}, in the path provided. -
Line 6: We use the
onUpdatehandler and pass thechangeandcontextobject parameters. Thechangeobject has abeforeandafterproperty we can use to read data before and after the triggered event occurs. -
Line 8: We access the value of the wildcard path from the context object and assign it to a
wildcardconstant. -** Lines 10, 11, 15, and 16:** We demonstrate how to check for the existence of the old and new data snapshots and access them if needed.
Note: Only the
onUpdateandonWriteevent handlers have access to thechangeobject that contains a snapshot of the path before and after the trigger event. ForonCreateandonDeleteevent types, thesnapshotobject returned is a snapshot of the data created or deleted. Read more about Realtime Database event triggers on the Firebase documentation.
Cloud Firestore triggers
Similarly, we can also trigger Cloud Functions for Firebase in response to events in Cloud Firestore. Cloud Firestore triggers work similar to Realtime Database triggers. However, they are accessed with functions.firestore and paths are referenced using the document function. Therefore, they wait for changes on a particular document path and trigger in response to those event types.
Cloud Firestore also has four triggers-onCreate, onDelete, onUpdate, and onWrite—which work the same as Realtime Database triggers discussed above:
- Line 4: We export our Cloud Firestore triggered function.
- Line 5: We define the document path for the function.
- Line 6: We specify an event type for the function trigger. In our case, we use
onUpdate. This accepts two parameters,changeandcontext. - Lines 7 and 8: We access the new and previous data snapshot at the location using the
changeobject. -Line 16: We terminate the function by returning a promise of a set operation.
Note: Our trigger must always point to a document, even if we’re using a wildcard. For example,
users/{userId}/{tasks}is not valid because{tasks}is a collection. Read more about Cloud Firestore event triggers on the Firebase documentation.
You may have been wondering why we have not required the Admin SDK to perform some write operations such as we do on line 16 above?
Note: This only occurs when we write to the same location that triggers the event. Hence, making changes to other locations outside the trigger event or to other Firebase services will require the Admin SDK. This is shown below:
On line 8 above, we use the Admin SDK to write to a document outside our trigger event.
Practice exercise
Study the highlighted lines in the widget below to understand authentication triggers:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
// auth background trigger
exports.userSignup = functions.auth.user().onCreate((user) => {
console.log("USER CREATED", user.displayName, user.uid);
return null;
});
// http request function
exports.getTasks = functions.https.onRequest((request, response) => {
admin
.database()
.ref("/tasks")
.get()
.then((snapshot) => {
response.send(snapshot.val());
})
.catch((error) => {
console.log(error.message);
response.status(500).send(error.message);
});
});
Steps to perform
- Run the widget above.
- Run the Cloud Functions deploy command on the terminal window provided. Don’t forget to include the required flags—
--flags—and their respective values—$VALUES. - Open the application using the unique Educative link provided on the widget.
- If logged in, log out of the existing account. Then, create a new user account using any sign-up method of your choice.
- Head over to the “Logs” section of the “Functions” section of the Firebase console to view the logged output.
Note: The widget above only demonstrates an Authentication-triggered event. A more practical use case is to send welcome emails to new users of an application using tools like Nodemailer and SendGrid.