Marking a user as offline

This is where things get a little hard.

The issue at hand is this — we need to mark the user as offline when the user navigates away from our application or closes the tab. But the moment the user does so, our client-side application’s execution context ends and it stops executing. So… how do we set the user as online: false now? 🤔

The onDisconnect() method

Firebase’s Realtime database (not the same as Firestore; it is the older version of their real-time database) has support for use-cases like this. Any reference made to a key-value pair in the database using the firebase.database() method comes with an onDisconnect() , which is a hook that fires when the client disconnects from the firebase database. It also allows you to specify the value(s) to be set for the key, when the client disconnects from the database.

All active connections to the database are listed in the /.list/connected collection in the Realtime database. Any time a client disconnects from the Realtime database, it is removed from this collection.

onDisconnect() example

Sadly that👆 is not a feature built into Firestore. 😔

Firebase Cloud Functions

Firebase also offers another service called Cloud Functions. Cloud functions are functions that you can write and deploy to firebase, to be hosted. These functions can be triggered by

HTTPS requests

Events emitted from other firebase features

The latter, is actually pretty interesting. Cloud functions have access to onChange hooks in other firebase products like the realtime database and Firestore.

Aha! We can finally put all three of these together to help us in marking a user as offline 🤓

The Solution

When we set the User’s online status in Firestore to online: true on loading up the application, let’s also create a record for the user in Firebase’s Realtime database. The key for this record will be the user ID (and this should match the corresponding Firestore document ID) the value set for this key will be 'online’ . Set up an onDisconnect() hook for the key that we will create in the Firebase Realtime database. When the user disconnects from the Realtime database, we need to set the key’s value to 'offline' . Prior to the above two steps, we will deploy a Cloud Function that listens on change events in the Firebase Realtime database. When the value changes for a key (where the key is the user ID) in the Realtime database, we capture the event, check if the value changed from 'online' to 'offline' , and then set the user’s online status in Firestore to online: false .

So, how does our Cloud Function look?

Cloud Function to check for real-time database updates

onUserStatusChanged will be triggered whenever any change occurs in the Firebase Realtime database to a key that matches this ref pattern — /status/{userId}

The function captures the event that is sent from the Realtime database to the Cloud Function, parses out the value from the event, checks if the value is 'offline' and if yes, it updates the Firestore document’s online status to online: false , thereby marking the user as offline in Firestore!

The process of setting up the Firebase Cloud Function and deploying it is a little bit out of the scope of this guide. It’s pretty simple and you can check the video below to get a better sense of it for yourself!