Firebase持久性 - onDisconnect与多个浏览器窗口

时间:2013-05-08 23:47:14

标签: javascript firebase

我们正在撰写一款监控在线状态的应用。在多种情况下,我们需要用户打开多个浏览器窗口。我们遇到的问题是,在辅助浏览器窗口中打开并运行firebase js代码后,用户将关闭该辅助窗口。这会将它们的状态设置为在主窗口中脱机,因为onDisconnect事件在辅助窗口中触发。

此方案是否有解决方法?这是否可以使用特殊的/.info/connected位置?

2 个答案:

答案 0 :(得分:8)

.info/connected状态数据仅告知给定客户端他们是否与Firebase服务器相关联,因此在这种情况下它不会帮助您。你可以试试其中一个:

如果变量脱机,请重置该变量

如果您有多个客户端监视同一个变量(多个窗口属于此类别),那么期望它们与存在值冲突是很自然的。让每个人监视变量以进行更改并根据需要进行更正。

var ref = firebaseRef.child(MY_ID).child('status');
ref.onDisconnect().remove();
ref.on('value', function(ss) {
   if( ss.val() !== 'online' ) {
      // another window went offline, so mark me still online
      ss.ref().set('online');
   }
});

这很快且易于实现,但可能很烦人,因为我的状态可能会闪烁到离线状态,然后重新联机到其他客户端。当然,这可以通过在触发UI更新之前对任何更改事件进行短暂延迟来解决。

为每个连接指定自己的路径

由于onDisconnect的目的是告诉您特定客户端是否脱机,因此我们应该自然地为每个客户端提供自己的连接:

var ref = firebaseRef.child(MY_ID).child('status').push(1);
ref.onDisconnect().remove();

使用此用例,每个连接的客户端都会在status下添加一个新的子项。如果路径不为null,则至少连接了一个客户端。

通过在status查找真实值来检查在线状态实际上非常简单:

firebaseRef.child(USER_ID).child('status').on('value', function(ss) {
    var isOnline = ss.val() !== null;
});

这样做的缺点是你真的只有status的价值(你不能把它设置为“空闲”和“在线”之类的东西),尽管这也可以解决一点点聪明才智。

在这种情况下,交易不起作用

我的第一个想法是尝试一个事务,所以你可以在打开/关闭每个窗口时增加/减少一个计数器,但transaction似乎没有onDisconnect方法。事件。这就是我提出多路径存在价值的方式。

答案 1 :(得分:1)

另一个简单的解决方案(使用angularfire2,但使用纯firebase类似):

const objRef = this.af.database.list('/users/' + user_id);
const elRef = objRef.push(1);
elRef.onDisconnect().remove();

每次打开新选项卡时,都会向阵列中添加一个新元素。 “onDisconnect”的引用与新元素有关,只有它被排除。

当此数组为空时,用户将处于脱机状态。