2016-06-02 14 views
7

Nach dem Anmelden habe ich einige Firebase-Referenzen abonniert und logge mich anschließend ab (FirebaseAuth.logout). Sobald ich mich abmelde, erhalte ich eine Firebase-Warnung in der Konsole: "Ausnahme wurde durch Benutzerrückruf ausgelöst. Fehler: permission_denied at ...." und dies wird eine tatsächliche Ausnahme. Während ich dieses Verhalten erwarte, was sind die besten Vorgehensweisen zum Protokollieren eines Benutzers, sodass ich diese Warnung/Ausnahme nicht sehe?Angularfire2: Abmeldeausnahme und bewährte Methoden

+0

Dies ist eine gute Frage, und es ist bedauerlich, dass niemand Einsicht zur Verfügung gestellt hat. –

Antwort

8

Ich hatte das gleiche Problem. Durch die folgende Quelle habe ich bisher eine Lösung gefunden, mit der ich noch nicht zufrieden bin. Source 1

Das Problem liegt in der Tatsache, dass es noch eine offene, nicht abgemeldete Subskription (Verbindung zu Firebase) irgendwo in Ihrem Code gibt.

Zum Beispiel habe ich

this.name_sub = this.af.database.object("https://stackoverflow.com/users/" + user.uid + "/name") 
    .subscribe(data => { 
    this.globals.user.name = data.$value; 
    } 
); 

, die völlig in Ordnung ist, bis zu dem Punkt Sie this.af.auth.logout(); sind aufgerufen wird. Wenn Sie Ihre Firebase-Sicherheitseinstellungen richtig eingerichtet haben, gibt Firebase einen Fehler aus, weil Sie nicht mehr mit dem Benutzer angemeldet sind - Sie sind jetzt anonym, und Sie sollten in einem Benutzerbereich gesperrt werden. Und da das oben genannte Abonnement noch aktiv ist, teilt Firebase Ihnen mit, dass Sie keinen Zugriff auf den Zielbenutzerbereich mit anonym haben.

Daher müssen Abonnements geschlossen werden. Eine Möglichkeit, dies zu tun, ist, fügt

irgendwo in Ihrer Komponente. Dies würde Ihr Abonnement schließen, wenn Sie Ihre . Leider ist das für mich nicht möglich, da ich mich in einer anderen Komponente abmelde. Die Art, wie ich es jetzt mache, ist das Schließen des Abonnements, gleich nachdem ein Wert erhalten wurde.

this.name_sub = this.af.database.object("https://stackoverflow.com/users/" + user.uid + "/name") 
    .subscribe(data => { 
    this.globals.user.name = data.$value; 
    this.name_sub.unsubscribe(); // <-- important part 
    } 
); 

Für mich ist das super kontraintuitiv. Ich denke, wir brauchen einen Weg, um Werte zu erhalten, ohne permanent den Datenkanal zu abonnieren und ohne zusätzliche Module zu importieren.

+0

Dies ist die richtige Antwort; Alle Abonnements müssen abgemeldet werden, bevor Sie sich abmelden. Im Allgemeinen wird dies in ngOnDestroy gemacht, wie von Niklas aufgezeigt, und ist trotzdem die beste Vorgehensweise, um Speicherlecks zu vermeiden. –

+0

Gibt es eine Möglichkeit, alles abzubestellen, bevor Sie sich abmelden? Ich finde es nur sehr mühsam, alle Abonnements zu finden und es ist auch sehr leicht in der Zukunft zu vergessen. – alltej

0

Es ist hässlich, aber funktioniert:

signOut(): void { 
    this.router.navigate(['/app').then(() => { 
     firebase.database().goOffline()  // <=== this eliminates error! 
     this.afAuth.auth.signOut() 
    }) 
    } 
+1

Bitte erläutern Sie, warum der Code funktioniert. –

Verwandte Themen