After logging in, I subscribe to some firebase refs, and then subsequently logout (FirebaseAuth.logout). Once I logout, I get a Firebase warning in the console: "Exception was thrown by user callback. Error: permission_denied at ...." and this becomes an actual exception. While I do expect to see this behavior, what are the best practices for logging a user out so I don't see this warning/exception?
问题:
回答1:
I had the same problem. Through the following source, I found a solution so far, wherewith I am not satisfied with yet. Source 1
The problem underlies in the fact, that there is still an open, not unsubscribed, subscription (connection to Firebase) somewhere in your code.
For example I did
this.name_sub = this.af.database.object("/users/" + user.uid + "/name")
.subscribe(data => {
this.globals.user.name = data.$value;
}
);
Which is totally fine, until the point you are invoking this.af.auth.logout();
. If you got your Firebase Security settings right, Firebase will throw an error, because you are not logged in with the user anymore - you are now anonymous, who should be blocked inside a user space. And because the above subscription is still active, Firebase tells you, that you do not have access with anonymous to the targeted user space.
Therefore, subscriptions must be closed. A way you could do this is, is adding
ngOnDestroy(){
this.name_sub.unsubscribe();
}
somewhere in your component. This would close your subscription when your component is destroyed. Unfortunately this is not possible for me, because I am doing the logout in another component. The way I am doing it now is closing the subscription, right after receiving a value.
this.name_sub = this.af.database.object("/users/" + user.uid + "/name")
.subscribe(data => {
this.globals.user.name = data.$value;
this.name_sub.unsubscribe(); // <-- important part
}
);
For me, this is super counter-intuitive. I think we need a way to receive value(s) without permanent subscribing to the data channel and without importing additional modules.
回答2:
It's ugly, but works:
signOut(): void {
this.router.navigate(['/app').then(() => {
firebase.database().goOffline() // <=== this eliminates error!
this.afAuth.auth.signOut()
})
}