Reactjs Firebase RDB存在未按预期工作

Reactjs Firebase RDB存在未按预期工作,reactjs,firebase,firebase-realtime-database,Reactjs,Firebase,Firebase Realtime Database,我试图检测玩家何时在线/离线,但似乎在交换角色时,所有角色都保持在线,直到应用程序关闭,而不是最小化,或空闲但实际关闭 在useffectcleanupreturn()中,我可以添加userStatusDatabaseRef.set(ISOFLINEFORDATABASE),它将正确显示脱机的角色。但是,当我关闭应用程序并调用onDisconnect时,所有字符的脱机状态将再次更新 那么,当角色不再处于活动状态时,如何正确地关闭该角色的连接呢 useEffect(() => { i

我试图检测玩家何时在线/离线,但似乎在交换角色时,所有角色都保持在线,直到应用程序关闭,而不是最小化,或空闲但实际关闭

useffect
cleanup
return()
中,我可以添加
userStatusDatabaseRef.set(ISOFLINEFORDATABASE)
,它将正确显示脱机的角色。但是,当我关闭应用程序并调用
onDisconnect
时,所有字符的脱机状态将再次更新

那么,当角色不再处于活动状态时,如何正确地关闭该角色的连接呢

useEffect(() => {
    if (!selectedCharacter) {
        return
    }

    console.log('selected ', selectedCharacter)
    const dbRef = database().ref('.info/connected')
    const userStatusDatabaseRef = database().ref('/status/' + selectedCharacter)
    const userStatusFirestoreRef = firestore().doc(`characters/${selectedCharacter}`)

    const onOnlineStateChange = snapshot => {
        if (snapshot.val() == false) {
        // Instead of simply returning, we'll also set Firestore's state
        // to 'offline'. This ensures that our Firestore cache is aware
        // of the switch to 'offline.'
            userStatusFirestoreRef.set(isOfflineForFirestore, {merge:true})
            return
        }

        userStatusDatabaseRef.onDisconnect().set(isOfflineForDatabase).then(function() {
            userStatusDatabaseRef.set(isOnlineForDatabase)
            // We'll also add Firestore set here for when we come online.
            userStatusFirestoreRef.set(isOnlineForFirestore, {merge:true})
        })
    }

    dbRef.on('value', onOnlineStateChange)
    return () =>{
        console.log('calling return & close for', selectedCharacter)
        dbRef.off('value', onOnlineStateChange)
    }

}, [selectedCharacter])


let isOfflineForFirestore = {
    state: 'offline',
    last_seen: firestore.FieldValue.serverTimestamp()
}

let isOnlineForFirestore = {
    state: 'online',
    last_seen: firestore.FieldValue.serverTimestamp()
}

var isOfflineForDatabase = {
    state: 'offline',
    last_seen: database.ServerValue.TIMESTAMP
}

var isOnlineForDatabase = {
    state: 'online',
    last_seen: database.ServerValue.TIMESTAMP
}

当客户端连接到Firebase服务器时,
.info/connected
节点为
true
。如果在“交换字符时”发生这种情况,则表示客户端仍连接到服务器。如果您的用例要求将旧字符标记为“脱机”,那么您必须自己在应用程序代码中执行此操作,就像您似乎已经完成的那样


但是,当我关闭应用程序并调用onDisconnect时,所有字符的脱机状态将再次更新

当服务器检测到客户端已断开连接时,您连接的任何组件都将触发。如果要取消先前添加的
onDisconnect
处理程序,可以调用其
cancel()
方法。从文件中:

var onDisconnectRef = presenceRef.onDisconnect();
onDisconnectRef.set('I disconnected');
// some time later when we change our minds
onDisconnectRef.cancel();