2017-11-29 3 views
0

Ich fand ein Beispiel von dem, was ich brauche in Google Firebase Dokumentation here.Überprüfen Sie, ob der Benutzer in Firebase online ist

Noch, ich möchte es ein wenig ändern, um es die Anwesenheit des Benutzers überprüfen jede Sekunde/10 Sekunden oder mindestens jede Minute abhängig davon, wie dies die Belastung auf dem Server beeinflussen wird, so kam ich mit dieser:

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); 
} 

aber hier ist das, was in der Konsole passiert, wenn ich es laufen:

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 

es die Funktion alle 10 Sekunden löst, aber es zeigt mir die beiden Ergebnisse, die ar e connected und disconnected gleichzeitig. (Tatsächlich gibt es eine Verzögerung von ungefähr 1 Sekunde.) Außerdem ignoriert es vollständig, ob der Benutzer angemeldet ist oder nicht und zeigt mir jedes Mal die gleichen Protokolle.

Ich möchte es isOnline Methode nur ausführen, wenn der Benutzer angemeldet ist (mit E-Mail und Passwort). Und wenn das wahr ist, sollte isOnline Anfrage an den Server senden, wenn der Benutzer alle N Sekunden online ist. Kann ich irgendetwas tun?

Es wäre viel besser, wenn ich überprüfen könnte, ob der Benutzer von der Serverseite verbunden ist, weil ich einige Aktionen durchführen muss, solange der Benutzer online bleibt. Aber ich bin mir nicht sicher, ob das möglich ist, also denke ich, dass es am besten ist, das Frontend zu überprüfen und Aktionen mit HTTP-Triggern auszulösen.

Antwort

1

Das aktuelle Verhalten ist darauf zurückzuführen, dass die Werte von snap in den Timer-Schließungen erfasst werden.

Wenn Sie isOnline einrichten, um das Ereignis value auszulösen, ruft Firebase die Methode jedes Mal auf, wenn sich der Wert des Schlüssels ändert. In diesem Fall hat Firebase zum ersten Mal isOnline aufgerufen, als festgestellt wurde, dass der Wert false ist. Anschließend wurde das zweite Mal nach der Anmeldung festgelegt und der Wert wurde true.

Jetzt innerhalb isOnline beginnen Sie Timeouts. Da die Funktion zweimal mit verschiedenen snap Objekten aufgerufen wurde, wurden zwei Timeouts erstellt. Aber beide haben ihre eigenen snap Objekte in ihren Schließungen, die auf die Werte festgelegt sind, wenn isOnline aufgerufen wurde.

Als Endergebnis haben Sie zwei ewige Timer laufen, die weiterhin die historischen snap Werte drucken :).

Wie Sie erwähnt, dass Sie nur etwas wollen regelmäßig tun, wenn und nur wenn der Benutzer online ist, können Sie dies stattdessen versuchen sollte:

für die Antwort
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); 
    } 
} 
+0

Thx! Jetzt habe ich noch ein Problem. 'setTimeOut's führt die Funktion nicht durch, nur eine Nachricht wird in der Konsole angezeigt. Und alte Probleme sind immer noch aktiv: Selbst wenn der Benutzer nicht in seinem Konto eingeloggt ist, löst 'doSomethingWhenOnline' aus. Ich habe also einige Fragen: Warum benutze ich 'setInterval' nicht, was vorher wirklich funktioniert hat und wie man dieses unerlaubte Auslösen beheben kann? Ich habe mehr Code hier gelassen, vielleicht könnte das helfen (vielleicht "onAuthStateChanged" bricht die ganze Sache, oder was?): Https://jsfiddle.net/o0s4zgzo/1/ – Telion

+0

Ich meine du sagtest, dass diese Methode 2 mal aufgerufen wurde, aber ich verstehe nicht warum. Vielleicht liegt es daran, dass sich der Verbindungsstatus erst ändert, nachdem der Benutzer eine Verbindung zum Server hergestellt hat.Aber warum gibt es jedes Mal "in false" aus, nachdem die Verbindung hergestellt wurde? Und schließlich, wie kann man hier die Authentifizierung der Benutzer einschließen? Ich meine, ich sollte nicht nur überprüfen, ob der Benutzer online ist, ich möchte auch überprüfen, ob der Benutzer ein Konto hat und sich damit eingeloggt hat, um ihm tatsächlich einige Punkte kontinuierlich zu generieren. – Telion

+0

'isOnline' wird zweimal von fb aufgerufen, da sich der Wert der Db-Referenz anfänglich von nichts zu" false "und dann zu" true "ändert. Sie sollten 'setInterval' nicht verwenden, da dies zu einem Wiedereintritt führen kann, wenn der erste Anruf auf eine Ajax-Rückkehr wartet. Sie sollten 'setTimeout' für Rückrufe bevorzugen, die Server-Operationen ausführen. Sie können den nächsten Anruf immer mit dem aktuellen verbinden, wie ich es in meinem Code getan habe. Ich würde empfehlen, einen SO-Chat zu starten, da es unmöglich ist, auf einzelne Fragen in Kommentaren zu antworten :). Es ist nur, dass ich nicht weiß, wie man eine Chat-Sitzung beginnt. Meistens kommt es, wenn wir einige Kommentare ausgetauscht haben. – hazardous

Verwandte Themen