簡體   English   中英

在 Firebase 中處理用戶的在線和離線狀態

[英]Handle users’ online and offline status in Firebase

我想在我的 web 應用程序中處理在線和離線狀態。 讓用戶可以看到誰在線,誰不在線。

我發現這個很棒的教程很好地解釋了它,但我被卡住了。

https://blog.campvanilla.com/firebase-firestore-guide-how-to-user-presence-online-offline-basics-66dc27f67802

我認為cloud-functions有問題,因為我在那里遇到錯誤。

此外,本教程來自 2017 年 12 月 15 日,我知道cloud-functions已更新,但我不知道如何更新代碼。

鏈接到文檔: https : //firebase.google.com/docs/functions/beta-v1-diff

有人可以看看教程,也許可以幫助我嗎?

雲功能:

 const functions = require('firebase-functions');
 const Firestore = require('@google-cloud/firestore');
 const firestore = new Firestore();

 exports.onUserStatusChanged = functions.database
  .ref('/status/{userId}') // Reference to the Firebase RealTime database key
  .onUpdate((event, context) => {

    const usersRef = firestore.collection('/users'); // Create a reference to 
    the Firestore Collection

    return event.before.ref.once('value')
      .then(statusSnapshot => snapShot.val()) // Get latest value from  the Firebase Realtime database
      .then(status => {
        // check if the value is 'offline'
        if (status === 'offline') {
          // Set the Firestore's document's online value to false
          usersRef
            .doc(event.params.userId)
            .set({
              online: false
            }, {
              merge: true
            });
        }
        return
      })
  });

我只是要發布功能齊全的代碼,以幫助像我一樣堅持使用它的其他人。

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});

                }
                return null;
            })
});

Firestore 官方文檔( 在 Cloud Firestore 中構建存在)中有一個更新的教程,解釋了如何設置 Firestore、實時數據庫和 Cloud Functions。

要知道用戶的存在,我們只需要一個事件。 Firebase 函數不是免費的加上部署等。所以對於事件,如果我們使用 Firebase 雲消息傳遞如何? 它是免費且無限制的。 即使通知被關閉,我們也可以處理消息事件。 接下來是我如何讓它在 React Native 上工作。

//通用應用代碼:

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


async requestUserPermission() {
    const authStatus = await messaging().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 apis
    this.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/offline
    var 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-*-
    });

FINALLY TRIGGER MULTICAST MESSAGE TO APPLICABLE USERS:

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 status
    notification: { 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);
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM