0

I am listening to .info/connected to figure out if my device is online or not. If it is online it adds a child with the device id to the database.

_firebaseDatabase.reference().child('.info/connected').onValue.listen((event) {
  if (event.snapshot.value == true) {
    setDeviceOnline(userUid: uid, deviceUid: deviceUid)
  }
});

I am using the onDisconnect callback on Firebase Realtime Database to remove this device id when the corresponding client disconnects.

Future<void> setDeviceOnline({String userUid, String deviceUid}) async {
  DatabaseReference currentDeviceConnection = _firebaseDatabase.reference().child('users/$userUid/connections').push();

  // Add this device to my connections list
  await currentDeviceConnection.set(deviceUid);

  // When I disconnect, remove this device
  currentDeviceConnection.onDisconnect().remove();
}

Now:

  1. When the client explicitly disconnects, the onDisconnect fires and removes the device id from the db.
  2. When I turn on airplane mode the onDisconnect fires after a short timeout and removes the device id from the db.
  3. When I turn on airplane mode and turn it back off before this timeout happens, the onDisconnect fires immediately when the client reconnects. Like it tells the db "I was offline"

The problem with point 3 is when the clients reconnects, onDisconnect fires and removes the present id from the database and due to the .info/connected listener which shows event.snapshot.value == true again, it immediately adds a new child with the device id to the database.

I think this works as intended. So I don't think this is a bug. But is there a way to prevent removing the child and adding a new one if there is still a corresponding child present in the db?

justchris
  • 123
  • 8

1 Answers1

1

Once the server detects that the original connection is gone (either on its own, or because the client tells it about it), it executes the onDisconnect handler that you set for that connection.

There is no way to prevent the removal of the previous connection node.

But since a new connection is established, your setDeviceOnline should generate a new currentDeviceConnection connect ID again. In fact, that is precisely why the presence system in the Firebase documentation generates a new ID each time it reconnects. Is that not happening for you?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Hi Frank. Thanks for your reply. Yes it is happening for me. So it is normal that the client is telling the db that is was offline for a short time and then the db fires `onDisconnect` even if the db itself did not notice the absent of the client yet? I mean the firing of `onDisconnect` is not really necessary since the client has already reconnected. I hope I explained this well enough. – justchris Dec 21 '21 at 09:02
  • There is a new connection from the same client, but the old connection is still gone. In your code, what I expect is that you get a new push ID for the new connection, and that the old push ID then disappears either immediately, or when the server detects it (which happens when the socket times out there). If that is not what you see happening, can you show a screenshot/gif of the database? – Frank van Puffelen Dec 21 '21 at 15:21