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?