Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to make the firebase realtime database presence system detect disconnect faster

I am creating a flutter app, it would be essential to detect almost immediately a user goes offline from the realtime/firestore database and notify other users of the same.

I have tried the recommended method of subscribing to .info/connected in the realtime DB and also update a firestore DB.

FirebaseDatabase.instance
        .reference()
        .child('.info')
        .child('connected')
        .onValue
        .listen((data) {
      if (data.snapshot.value == false) {
        // Internet has been disconnected
        setState(() {
          state.connected = false;
        });
        userFirestoreRef.updateData({
          'status': 'offline',
          'lastChanged': FieldValue.serverTimestamp(),
        });
      }
      userDbRef.onDisconnect().update({
        'status': 'offline',
        'lastChanged': ServerValue.timestamp
      }).then((_) async {
        // This resolves as soon as the server gets the request, not when the user disconnects
        setState(() {
          state.connected = true;
        });
        await userDbRef.update({
          'status': 'online',
          'lastChanged': ServerValue.timestamp,
        }).catchError((e) => debugPrint('Error in realtime db auth, $e'));

        await userFirestoreRef.updateData({
          'status': 'online',
          'lastChanged': FieldValue.serverTimestamp(),
        }).catchError((e) => debugPrint('Error in firestore auth, $e'));
      });

Once the internet is off, it takes about 1.5 minutes for the realtime db to detect the user disconnected, I would like this to maybe be 10 seconds maximum.

like image 424
alfiepoleon Avatar asked Jun 10 '19 20:06

alfiepoleon


1 Answers

There are two ways a client can disconnected:

  • a clean disconnect, where the client lets the server know that it's disappearing.

  • a dirty disconnect, where the client disappears and it's up to the server to detect this condition.

For clean disconnects, the onDisconnect writes you defined will run immediately.

Dirty disconnects depend on socket time-outs, which means it may take multiple minutes before your onDisconnect writes happen. There is nothing you can do about this behavior, as it's an inherent part of how sockets work.

If you want a faster way to detect what clients are still connected, you can write a keep-alive in the database. Essentially: every 10 seconds write a sentinel value from every client.

like image 177
Frank van Puffelen Avatar answered Oct 07 '22 13:10

Frank van Puffelen