Firebase persistance - onDisconnect with multiple browser windows

前端 未结 2 1374
北荒
北荒 2021-02-09 05:27

We\'re writing an app that monitors online presence. There are multiple scenarios where we need the user to have more than one browser window open. We\'re running into a probl

相关标签:
2条回答
  • 2021-02-09 06:03

    The .info/connected presence data only tells a given client if they are linked up to the Firebase server, so it won't help you in this case. You could try one of these:

    Reset the variable if it goes offline

    If you have multiple clients monitoring the same variable (multiple windows falls into this category), it's natural to expect them to conflict about presence values. Have each one monitor the variable for changes and correct it as necessary.

    var ref = firebaseRef.child(MY_ID).child('status');
    ref.onDisconnect().remove();
    ref.on('value', function(ss) {
       if( ss.val() !== 'online' ) {
          // another window went offline, so mark me still online
          ss.ref().set('online');
       }
    });
    

    This is fast and easy to implement, but may be annoying since my status might flicker to offline and then back online for other clients. That could, of course, be solved by putting a short delay on any change event before it triggers a UI update.

    Give each connection its own path

    Since the purpose of the onDisconnect is to tell you if a particular client goes offline, then we should naturally give each client its own connection:

    var ref = firebaseRef.child(MY_ID).child('status').push(1);
    ref.onDisconnect().remove();
    

    With this use case, each client that connects adds a new child under status. If the path is not null, then there is at least one client connected.

    It's actually fairly simple to check for online presence by just looking for a truthy value at status:

    firebaseRef.child(USER_ID).child('status').on('value', function(ss) {
        var isOnline = ss.val() !== null;
    });
    

    A downside of this is that you really only have a thruthy value for status (you can't set it to something like "idle" vs "online"), although this too could be worked around with just a little ingenuity.

    Transactions don't work in this case

    My first thought was to try a transaction, so you could increment/decrement a counter when each window is opened/closed, but there doesn't seem to be a transaction method off the onDisconnect event. So that's how I came up with the multi-path presence value.

    0 讨论(0)
  • 2021-02-09 06:11

    Another simple solution (Using angularfire2, but using pure firebase is similar):

    const objRef = this.af.database.list('/users/' + user_id);
    const elRef = objRef.push(1);
    elRef.onDisconnect().remove();
    

    Each time a new tab is opened a new element is added to the array. The reference for "onDisconnect" is with the new element, and only it is excluded.

    The user will be offline when this array is empty.

    0 讨论(0)
提交回复
热议问题