Firebase persistance - onDisconnect with multiple browser windows

We are writing an application that tracks online presence. There are several scenarios in which the user needs to open several browser windows. We encounter a problem when a user, opening and running the firebase js code in the secondary browser window, closes this secondary window. This sets their offline presence in the main window because the onDisconnect event is fired in the secondary window.

Is there a workaround for this scenario? This is where you can use the special place / .info / connected?

+4
source share
2 answers

The presence information .info/connected indicates only to this client, if they are connected to the Firebase server, so in this case it will not help you. You can try one of them:

Reset variable if disabled

If you have multiple clients controlling the same variable (multiple windows fall into this category), it is natural to expect them to conflict with presence values. Each of them controls the variable for changes and corrects 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 quick and easy to implement, but it can be annoying, as my status can flicker offline, and then reconnect to other clients. Of course, this could be solved by putting a slight delay on any change event before it triggers an update to the user interface.

Give each connection its own path

Since the goal of onDisconnect is to tell you that a particular client goes offline, we must naturally provide each client with its own connection:

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

In this 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 is actually quite simple to check for availability on the Internet, just looking for the true value in status :

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

The disadvantage of this is that you really only have a critical value for status (you cannot set it to something like "idle" and "online"), although this too could be handled with a little ingenuity.

In this case, the transactions do not work

My first thought was to try a transaction so that you can increment / decrement the counter when every window is open / close, but there is no transaction method outside the onDisconnect event. So, as I came up with the ambiguous meaning of presence.

+7
source

Another simple solution (using angularfire2, but using pure firebase seems to be):

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

Each time a new tab opens, a new element is added to the array. The link to "onDisconnect" is associated with the new item, and only it is excluded.

The user will be disconnected when this array is empty.

0
source

Source: https://habr.com/ru/post/1479829/


All Articles