如何在React中使用Firebase V9检测用户在线/离线状态
Firebase V9 用户在线/离线状态显示异常:
snap.val() 始终返回 false 问题描述
我开发了一款聊天应用,需要在Firebase V9中实现用户在线、离线状态显示,覆盖窗口/标签页关闭、断开连接、登出等场景。已配置好firebase.js,但编写代码时遇到问题:即使指定UID的用户处于在线状态,监听.info/connected返回的snap.val()始终为false。
配置代码(firebase.js)
import { initializeApp } from 'firebase/app'; import { getAuth } from 'firebase/auth'; import { getStorage } from 'firebase/storage'; import { getFirestore } from 'firebase/firestore'; import { getDatabase } from 'firebase/database'; const firebaseConfig = { apiKey: apikey, authDomain: 'xxxxx.firebaseapp.com', projectId: 'xxxx', storageBucket: 'xxxx.appspot.com', messagingSenderId: 'xxxxxx', appId: '1:xxxxxxxx:web:xxxxxxx', }; export const app = initializeApp(firebaseConfig); export const auth = getAuth(); export const storage = getStorage(); export const db = getFirestore(); export const firebaseDb = getDatabase(app);
尝试的代码
useEffect(() => { const connectedRef = ref(firebaseDb, '.info/connected'); const uid = '3bEw4VqpMieSzR8NBfDz6XqG33l1'; const myConnectionsRef = ref(firebaseDb, 'users', uid); console.log(myConnectionsRef, 'myConnectionsRef'); onValue(connectedRef, (snap) => { console.log(snap.val(), 'snap'); if (snap.val() === true) { console.log('TRUE'); if (user) { set(myConnectionsRef, 'connected'); updateFirestoreUser(user, true); } } else { console.log('FALSE'); updateFirestoreUser(user, false); } //onDisconnect(myConnectionsRef) //.set("disconnected") //.then(() => { // updateFirestoreUser(user, false); //}); }); }, []);
补充:更新后问题依旧,即使指定UID用户在线,snap.val()仍显示false。
问题排查与解决方案
1. 实时数据库引用路径错误
你创建myConnectionsRef的写法有误,ref函数的路径参数需要正确拼接:
// 错误写法 const myConnectionsRef = ref(firebaseDb, 'users', uid); // 正确写法1:拼接路径字符串 const myConnectionsRef = ref(firebaseDb, `users/${uid}`); // 正确写法2:使用child方法 const myConnectionsRef = ref(firebaseDb, 'users').child(uid);
原写法会导致引用路径异常,进而影响状态监听逻辑。
2. 检查实时数据库规则
确保数据库规则允许读取.info/connected节点,默认规则支持,但自定义规则时需保留权限:
{ "rules": { ".info": { ".read": true }, // 其他自定义规则... } }
3. 完善离线状态处理(恢复onDisconnect)
onDisconnect是实现离线状态自动更新的核心,需修正并恢复:
useEffect(() => { if (!user) return; // 先判断用户是否存在,避免空值错误 const connectedRef = ref(firebaseDb, '.info/connected'); const userStatusRef = ref(firebaseDb, `users/${user.uid}/status`); // 用独立字段存储状态更清晰 // 取消监听的函数,组件卸载时执行 const unsubscribe = onValue(connectedRef, (snap) => { if (snap.val() === true) { // 在线时设置状态,并绑定离线触发逻辑 set(userStatusRef, 'online') .then(() => { onDisconnect(userStatusRef).set('offline'); updateFirestoreUser(user, true); }); } else { updateFirestoreUser(user, false); } }); return () => unsubscribe(); }, [user]); // 依赖项添加user,确保用户状态变化时重新执行监听
4. 修复useEffect依赖项缺失
原代码依赖项为空数组,user状态变化时不会重新执行监听逻辑,需将user加入依赖数组。
5. 验证网络与数据库连接
检查客户端网络状态,确认能正常访问Firebase实时数据库;同时验证数据库中users节点的结构是否符合预期。
内容的提问来源于stack exchange,提问作者Srivathsa k m
相关产品推荐
相关产品推荐

