【问题标题】:Observe multiple children of same node in Firebase Realtime Database在 Firebase 实时数据库中观察同一节点的多个子节点
【发布时间】:2020-05-06 09:22:57
【问题描述】:

我使用 Firebase 实时数据库将用户的 uid 解析为临时 peerId。每个用户在上线时创建此 peerId,并在下线之前将其设置为 null。 因此,如果在 /peerIdByUid/ 中找到用户的 uid,则用户在线。

这是我的数据的样子:

/peerIdByUid/$uid = $peerId

每个用户都是一个节点,其 uid 为 key,peerId 为 value。

每个用户都有朋友,需要知道他们是否在线、离线等。

我需要为每个引用创建一个观察者吗?

例子:

//for each friend
firebase.database().ref('/peerIdByUid/' + friendUserId).on('value').then(function(snapshot) {
  //display friend online/offline
});

有没有更优雅的解决方案,我只用一个观察者观察用户的朋友?

而且我不想做一些昂贵的事情,比如:

firebase.database().ref('/peerIdByUid').on("value")...

因为这会将所有用户的数据下载到客户端,可能会让我破产。

我正在考虑类似的事情

const refsToFriends = ['/peerIdByUid/firend1', '/peerIdByUid/friend2', ...];
firebase.database().observe(refToFriend).on('value').then(...);

另一方面,根据这个答案:What does a Firebase observer actually do? 这没有意义,我可以在每个朋友的参考上创建一个观察者。

我还考虑在每个用户的好友列表中写入 peerId。但这会将所需的空间和流量乘以每个朋友的数量。并且 peerId 变化非常频繁。所以我想把它放在一个地方。

【问题讨论】:

    标签: javascript firebase firebase-realtime-database


    【解决方案1】:

    我用观察者观察每个朋友 peerId,但将每个观察者存储到字典中以防止一个人有多个观察者。我还发现了这个:Enabling Offline Capabilities in JavaScript

    断开连接onDisconnect() 在客户端与数据库断开连接时触发操作。如果浏览器崩溃,unload 事件(我使用的)不会被触发,但onDisconnect() 会触发。

    注册 peerId 并在断开连接时将其删除:

    //this function registers the peerId to the uid and saves the current timstamp
    //it also deletes the peerId and timestamp on disconnect
    async registerPeerId(uid: string, peerId: string) {
        const peerIdRef = firebase.database.ref(`peerIdByUid/${uid}`);
        await peerIdRef.set({
            peerId,
            timestamp: db.ServerValue.TIMESTAMP
        });
        peerIdRef.onDisconnect().set(null);
    }
    

    听朋友在线和离线:

    //global dictionary to store observer for friends
    const friendListeners: Dictionary<Function> = {}; 
    // some function to that is called on initalization of app
    async function loadFriends(){
      const friends = await findFriends(); //load friends
      await Promise.all(friends.map(async (f: Friend) => {
        listenToFriend(f);
        // other stuff: e.g. connecting to friend
      });
    }
    
    function listenToFriend(friend: Friend) {
      //check if an observer exists
      if(!(friend.uid in friendListeners)) {
        friendListeners[friend.uid] = firebase.database
                                      .ref(`peerIdByUid/${friend.uid}`)
                                      .on("value", (snapshot: db.DataSnapshot) => {
          if (snapshot.exists()) {
            let {peerId} = snapshot.val();
            //this stores the new peerId into a global store that can be checked fast and cheap
            upsertPeerId(friend.uid, peerId);
          } else {
            // sets peerId to null to show that user is offline
            upsertPeerId(friend.uid, null);
          }
        });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 1970-01-01
      • 2020-06-26
      相关资源
      最近更新 更多