Skip to content Skip to sidebar Skip to footer

Handle Users’ Online And Offline Status In Firebase

I want to handle the online and offline status in my webapp. So that users can see who is online and who not. I found this awesome tutorial which explain it very good, but I am stu

Solution 1:

There is an updated tutorial in the official Firestore documentation (Build presence in Cloud Firestore) that explains how to set up Firestore, Realtime Database, and Cloud Functions.

Solution 2:

I'm just going to post the fully functional code to help others who stuck with it like me.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const firestore = functions.firestore;

exports.onUserStatusChange = functions.database
    .ref('/status/{userId}')
    .onUpdate((event, context) => {

        var db = admin.firestore();
        var fieldValue = require("firebase-admin").firestore.FieldValue;

        const usersRef = db.collection("users");
        var snapShot = event.after;

        return event.after.ref.once('value')
            .then(statusSnap => snapShot.val())
            .then(status => {
                if (status === 'offline'){
                    usersRef
                        .doc(context.params.userId)
                        .set({
                            online: false
                        }, {merge: true});

                }
                returnnull;
            })
});

Solution 3:

To know the user presence, all we need is an event. Firebase Functions aren't free plus deploy etc. So for event, how if we use Firebase Cloud Messaging? it's free and unlimited. We can handle messaging events even if notificatiions are turned off. What follows is how I have it to work on React Native.

//GENERAL APP CODE:

import auth  from'@react-native-firebase/auth';
import database from'@react-native-firebase/database';
import messaging from'@react-native-firebase/messaging';


asyncrequestUserPermission() {
    const authStatus = awaitmessaging().requestPermission();
    const enabled = 
      authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
      authStatus === messaging.AuthorizationStatus.PROVISIONAL;
      
    if (enabled) {
        console.log('Authorization status:', authStatus);
    }
}

updateFCMToken() {
    if (!messaging().isDeviceRegisteredForRemoteMessages)
    messaging().registerDeviceForRemoteMessages()
        .then((value) => {
            messaging().getToken().then( async (fcmToken) => {
            // Update backend (e.g. Firestore) with our token for the user
            });
    });
}

componentDidMount(){
    requestUserPermission();
    updateFCMToken();
    
    //-*-Update Online/Offline in REALTIMEDATABASE-*-*-*-*if (auth().currentUser) {
        var userStatusDatabaseRef = database().ref('/users/' + auth().currentUser.uid);
        var isOfflineForDatabase = {
            status: 'offline',
            last_changed: database.ServerValue.TIMESTAMP,
        };
        var isOnlineForDatabase = {
            status: 'online',
            last_changed: database.ServerValue.TIMESTAMP,
        };
        database().ref('.info/connected').on('value', 
        function (snapshot) {
            userStatusDatabaseRef.onDisconnect().set(
                isOfflineForDatabase).then(
                    function () {
                        userStatusDatabaseRef.set(isOnlineForDatabase);
                });
        });
    }
    
    //-*-Register Handle Message-*-*-*-*//-*-Here you get uid of user with online/offline status which you triggered using admin apisthis.unsubscribeMessage = messaging().onMessage(remoteMessage => {
        Alert.alert(re moteMessage.notification.title, 
        remoteMessage.notification.body);
    });
}

//ADMIN APP CODE WHICH IS A SIMPLE NODEJS SERVER://-*-In below code admin app listens when user is online/offlinevar userStatusOnlineRef =  database().ref('/users').orderByChild('status').equalTo('online');
    userStatusOnlineRef.on('value', (snapshot) => {
        //-*-Get the uid and use it to send to relevant users-*-
    });

    var userStatusOnlineRef =  database().ref('/users').orderByChild('status').equalTo('offline');
    userStatusOnlineRef.on('value', (snapshot) => {
        //-*-Get the uid and use it to send to relevant users-*-
    });

FINALLYTRIGGERMULTICASTMESSAGETOAPPLICABLEUSERS:

var admin = require('firebase-admin');
const serviceAccount = require("./serviceAvccount.json");

admin.initializeApp({
    credential: admin.credential.cert(serviceAccount),
    databaseURL: "https://***.firebaseio.com"
});

const registrationTokens = [
    '....',
    '....',
];

const message = {
    //-*-Pass uid and online/offline statusnotification: { title: '', body: '', element: '', element: '' },
    tokens: registrationTokens,
};

admin.messaging().sendMulticast(message)
    .then((response) => {
        if (response.successCount > 0)
        console.log(response.successCount + ' messages were sent successfully');

        if (response.failureCount > 0) {
            const failedTokens = [];
            response.responses.forEach((resp, idx) => {
                if (!resp.success) {
                    failedTokens.push(registrationTokens[idx]);
                }
            });
            console.log('List of tokens that caused failures: ' + failedTokens);
        }
    })
    .catch((error) => {
        console.log('Error sending message:', error);
    });

Post a Comment for "Handle Users’ Online And Offline Status In Firebase"