检查Firebase中的用户是否在线

时间:2017-11-29 06:52:14

标签: javascript firebase firebase-realtime-database

我在Google Firebase文档here中找到了我需要的示例。

仍然,我想稍微修改它,使其每秒/ 10秒或至少每分钟检查用户的存在,具体取决于这将如何影响服务器上的负载,所以我提出了这个:

TestApp.prototype.initFirebase = function() {
    this.database = firebase.database();
    this.database.ref(".info/connected").on("value", this.isOnline.bind(this));
};

TestApp.prototype.isOnline = function(snap) {
    var i=0;
    console.log(snap.val());
    setInterval(function() {
        if (snap.val() === true) {
            console.log("connected"+(i+=10));
        } else {
            console.log("not connected");
        }
    }, 10000);
}

但是如果我运行它,控制台中会发生什么:

main.js:34 false
main.js:91 User signed out
main.js:34 true
main.js:39 not connected
main.js:37 connected10
main.js:39 not connected
main.js:37 connected20
main.js:39 not connected
main.js:37 connected30
main.js:39 not connected
main.js:37 connected40

它每隔10秒触发一次该功能,但它同时显示connecteddisconnected两个结果。 (实际上,延迟大约1秒)此外,如果用户登录或不登录,它会完全忽略,并且每次都显示相同的日志。

我希望它仅在用户登录时使用isOnline方法(使用电子邮件和密码)。如果确实如此isOnline如果用户每隔N秒在线,则应向服务器发送请求。有什么我能做的吗?

如果我可以检查用户是否从服务器端连接会好得多,因为只要用户保持在线,我就需要做一些操作。但我不确定这是否可能,所以我认为最好的办法是检查前端并触发HTTP触发器的操作。

1 个答案:

答案 0 :(得分:1)

当前行为是由于在计时器闭包中捕获snap的值。

当您设置isOnline以触发value事件时,Firebase会在每次密钥值更改时调用该方法。在这种情况下,Firebase在确定值为isOnline时首次调用false,然后在登录成功后第二次调用true

现在在isOnline内,您正在开始超时。由于使用不同的snap对象调用了两次函数,因此创建了两个超时。但是它们的闭包中都有自己的snap个对象,这些对象在调用isOnline时固定为值。

作为最终结果,您有两个永久定时器正在运行,可以继续打印历史snap值:)。

正如您所提到的那样,当且仅当用户在线时,您才想定期做某事,您应该尝试这样做:

isOnline : function(snap){
  let test = snap.val();
  // If the user is not online,
  // check if we had the timer set,
  // as we should clear it now.
  // It essentially means user went offline.
  if (!test && this.whenOnline) {
    clearTimeout(this.whenOnline);
    this.whenOnline = null;
    return;
  }

  // If the user is not online, return.
  if (!test){
    return;
  }

  // User is online. Install the timer if we haven't.
  if (!this.whenOnline){
    this.whenOnline = setTimeout(this.doSomethingWhenOnline, 10000);
  }
}

doSomethingWhenOnline : function(){
  // whatever;

  // Cue the next timer again, notice we only install if
  // the previous instance has not been cleared by the
  // isOnline handler.
  if (this.whenOnline){
    this.whenOnline = setTimeout(this.doSomethingWhenOnline, 10000);
  }
}