Angular 2 - Firebase maintaining logged in state on page refresh

I don't really know the answer since I don't use firebase so those are more pointers

Guess 1: the user is in an intermediate state

The function that runs the authentication in the background hasn't run yet when the canActivate method does. Thus the current user isn't set yet. I guess firebase simply goes to your local storage and check if the token is valid. If it's what it does then simply make sure that this happens before canActivate.

However it could run before and have the current user still undefined if it's asynchronous which is quite possible. Then you'll have to make sure the canActivate runs after it resolves.

Actually, better yet: use the observable in your can activate method as seen:

  • here

  • here

code:

 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.af.auth.map((auth) => {
        if (!auth) {
          this.router.navigateByUrl('login');
          return false;
        }
        return true;
    }).take(1);
  }

Guess 2: You have to store something in local storage.

Those authentication services usually requires to store a token in localstorage, this token is then used to authenticate the user upon page refresh. Of what I can read this is done in the background with firebase. You could still check the local storage/ session storage just to be sure you see info's there.

If you don't see anything relevant in localStorage/sessionStorage, chances are you have to put in there something upon login.


I had the same problem as yours, i did the following to solve it with localStorage:

login(email, password): Observable<AuthInfo> {
    return this.fromFirebaseAuthPromise(this.afAuth.auth.signInWithEmailAndPassword(email, password));
}

I just added localStorage.setItem("user", this.afAuth.auth.currentUser.uid); to the login response and localStorage.removeItem("user"); to the logout method.

fromFirebaseAuthPromise(promise): Observable<any> {

const subject = new Subject<any>();

promise
  .then(res => {
      const authInfo = new AuthInfo(this.afAuth.auth.currentUser.uid);
      this.authInfo$.next(authInfo);
      subject.next(res);
      subject.complete();
      localStorage.setItem("user", this.afAuth.auth.currentUser.uid);
    },
    err => {
      this.authInfo$.error(err);
      subject.error(err);
      subject.complete();
    });

    return subject.asObservable();
}



logout() {
    this.afAuth.auth.signOut();
    localStorage.removeItem("user");
    this.authInfo$.next(AuthService.UNKNOWN_USER);
    this.router.navigate(['/login']);
}

and changed the canActivate() method to the following:

canActivate() {
        //you can check token is exists or not here
        if (localStorage.getItem('user')) {
            console.log("user ist logged in ....", localStorage.getItem('user'));

            return true;
        } else {
            console.log("user is not logged in");

            this.router.navigate(['/login']);
            return false;
        }
    }