i wrote following simple presence code in javascript (based upon https://firebase.google.com/docs/database/web/offline-capabilities#section-sample):
var app = firebase.initializeapp(config); var mainref = app.database().ref(); var session = null; var connected = false;  function do_sessionsubscribe(subscription) {     if (!subscription.entry) {         subscription.entry = subscription.parent.push(true);         subscription.entry.ondisconnect().remove();     } }  function do_sessionunsubscribe(subscription) {     if (subscription.entry) {         subscription.entry.remove();         subscription.entry = null;     } }  mainref.child(".info/connected").on("value", function(snap) {     connected = snap.val() === true;     if (session) {         if (connected) {             do_sessionsubscribe(session.subscription);         } else {             // workaround             //do_sessionunsubscribe(session.subscription);         }     } });  function closesession() {     if (session) {         do_sessionunsubscribe(session.subscription);         session = null;     } }  function opensession(uid) {     session = { uid: uid, subscription: { parent: mainref.child("session/user/" + uid), entry: null } };     if (connected) {         do_sessionsubscribe(session.subscription);     } }  app.auth().onauthstatechanged(function(user) {     closesession();     if (user && user.uid) {         opensession(user.uid);     } });   security rules:
"session": {     "user": {         "$uid": {             ".read": "auth.uid === $uid",             ".write": "auth.uid === $uid",             "$session": {                 ".validate": "newdata.val() === true"             }         }     }, }   the idea each active connection of user create /session/user/$uid/$session upon connecting/signing in , delete when disconnecting/signing out.
therefore in order obtain list of online users should sufficient /session/user shallow=true.
the problem session isn't cleaned , stays under /session/user/$uid forever. interpreted if user online time.
i discovered in order reproduce issue sufficient block access securetoken.googleapis.com (i use google authentication), wait hour , close browser.
i tried workaround problem calling remove() on disconnection. cleans stale session client gets reconnected (this late, better late never...). however, when user closes it's browser after loosing internet connection , auth token expires before sockets time out, stale session persists forever.
- what value of auth.uid used during checking security rules when auth token used registering ondisconnect() action expired?
 - how make presence system reliable without compromising security?