[英]Handle users’ online and offline status in Firebase
我想在我的 web 應用程序中處理在線和離線狀態。 讓用戶可以看到誰在線,誰不在線。
我發現這個很棒的教程很好地解釋了它,但我被卡住了。
我認為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.