我想在我的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
})
});
答案 0 :(得分:3)
Firestore 官方文档 (Build presence in Cloud Firestore) 中有一个更新的教程,解释了如何设置 Firestore、实时数据库和 Cloud Functions。
答案 1 :(得分:0)
我将发布完整功能的代码,以帮助那些像我一样坚持使用它的人。
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;
})
});
答案 2 :(得分:0)
要了解用户的存在,我们只需要一个事件。 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);
});