Fir*_* OS 5 firebase firebase-authentication firebase-realtime-database
我在 JavaScript 中编写了以下简单的存在代码(基于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);
}
});
Run Code Online (Sandbox Code Playgroud)
安全规则:
"session": {
"user": {
"$uid": {
".read": "auth.uid === $uid",
".write": "auth.uid === $uid",
"$session": {
".validate": "newData.val() === true"
}
}
},
}
Run Code Online (Sandbox Code Playgroud)
这个想法是,用户的每个活动连接将/session/user/$uid/$session在连接/登录时创建,并在断开/注销时删除它。
因此,为了获得在线用户列表,/session/user使用shallow=true.
问题是有时一个会话没有被清理干净并且/session/user/$uid永远停留在下面。然后将其解释为用户是否一直在线。
我发现为了轻松重现该问题,只需阻止对 securetoken.googleapis.com 的访问(我使用 Google 身份验证),等待一个小时并关闭浏览器即可。
我试图通过在断开连接时调用 remove() 来解决这个问题。一旦客户端重新连接,这就会清理陈旧的会话(这太晚了,但迟到总比没有好......)。但是,当用户在失去 Internet 连接后关闭它的浏览器,然后身份验证令牌在套接字超时之前过期时,陈旧的会话将永远存在。
| 归档时间: |
|
| 查看次数: |
614 次 |
| 最近记录: |