Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularfire2: logout exception & best practices

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?

like image 316
Norman Cheng Avatar asked Jun 02 '16 16:06

Norman Cheng


1 Answers

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.

like image 172
Niklas Avatar answered Oct 27 '22 00:10

Niklas