Наблюдать за несколькими дочерними элементами одного и того же узла в базе данных Firebase Realtime - PullRequest
0 голосов
/ 06 мая 2020

Я использую Firebase Realtime Database для преобразования uid пользователя во временный peerId. Каждый пользователь создает этот peerId, когда они выходят в сеть, и устанавливает для них значение null, прежде чем они go отключатся. Таким образом, пользователь находится в сети, если его uid находится в /peerIdByUid/.

Вот как выглядят мои данные:

/peerIdByUid/$uid = $peerId

Каждый пользователь является узлом с его uid в качестве ключа и peerId в качестве значения.

У каждого пользователя есть друзья, и ему нужно знать, если они в сети, отключены ли они и т. д. c.

Нужно ли мне создавать наблюдателя для каждой ссылки?

Пример:

//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(...);

С другой стороны рука, согласно этому ответу: Что на самом деле делает наблюдатель Firebase? это не имеет смысла, и я могу просто создать наблюдателя по ссылке каждого друга.

Я также думал о написании peerIds в списке друзей каждого пользователя. Но это умножит количество необходимого места и трафика c на количество каждого друга. И peerId меняется очень часто. Так что я хочу это в одном месте.

1 Ответ

0 голосов
/ 06 мая 2020

Я наблюдал за каждым другом peerId с наблюдателем, но сохранил каждого наблюдателя в Словаре, чтобы предотвратить несколько наблюдателей для одного человека. Я также нашел это: Включение возможностей автономного режима в JavaScript

onDisconnect : onDisconnect() запускает операцию, когда клиент отключается от базы данных. Если браузер дает сбой, событие выгрузки (которое я использовал) не запускается, но будет 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);
      }
    });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...