onDisconnect fires when client reconnects

585 Views Asked by At

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?

1

There are 1 best solutions below

2
Frank van Puffelen On

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?