What is Push and Remove required for, is it only for multiple devices?
https://firebase.google.com/docs/database/flutter/offline-capabilities#section-sample
Code 1:
final myConnectionsRef =
FirebaseDatabase.instance.ref("users/joe/connections");
final lastOnlineRef =
FirebaseDatabase.instance.ref("users/joe/lastOnline");
final connectedRef = FirebaseDatabase.instance.ref(".info/connected");
connectedRef.onValue.listen((event) {
final connected = event.snapshot.value as bool? ?? false;
if (connected) {
final con = myConnectionsRef.push();
con.onDisconnect().remove();
lastOnlineRef.onDisconnect().set(ServerValue.timestamp);
con.set(true);
}
});
Code 2:
final connectedListRef =
FirebaseDatabase.instance.ref('.info/connected');
final userStatusDatabaseRef =
FirebaseDatabase.instance.ref().child('users/joe');
connectedListRef.onValue.listen((event) {
final connected = event.snapshot.value as bool? ?? false;
if (connected) {
userStatusDatabaseRef
.set({'online': true, 'lastOnline': ServerValue.timestamp});
userStatusDatabaseRef.onDisconnect().set({
'online': false,
'lastOnline': ServerValue.timestamp,
});
}
});
CodePudding user response:
A single device will end up connecting to the Firebase Realtime Database server multiple times, both as part of its initialization process and when there is a temporary drop in the connection (which happens much more frequently than you may realize).
By calling push()
you ensure that each such connection is tracked separately, and the onDisconnect
for one can't interfere with the other. If you don't call push, the flow may be:
- Connect to server
- Write the marker
- Register the
onDisconnect
handler for the marker - The connection is dropped, but the server isn't notified of this. In this case, the server won't know that the client is disconnected until the socket times out, which may take some time.
- Meanwhile the client connects to the server again
- And writes the same marker.
- And registers another
onDisconnect
handler for the marker - And then... the
onDisconnect
from #3 fires, removing the marker that was written in both #2 and #6. - So now we have the client connected over the connection it made in #5, but no marker in the database.
I hope this flow clarifies why you need a separate marker for each time the client connects to the database server. The way to then detect whether a client is connected is to check if there are any nodes under the users/joe/connections
node.