Marking user as offline

The issue at hand is this — we need to mark the user as offline when the user closes our application or device shuts off or network failure happens or any other kind of exit happens. 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? Also, note that along with online flag, we have to update the last online time as to show keep record of when user went offline.

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 FirebaseDatabase.getInstance() 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() method example

Unfortunately, there is no such method of onDisconnect() in Firestore. So, we have to use Firebase with Firestore using Cloud Functions to make a workaround for this.

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 (Thanks to Abinav Seelan 🤓)

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, this is how does our Cloud Function looks like:

Firebase Cloud Function for User Presence Demo

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