Angular 2 - Firebase maintaining logged in state on page refresh

Viewed 4958

So I'm really close to having this figured out. Basically, I have login working and I have the code setup to watch for onAuthStateChanged, but the problem is that when I refresh the page, even if the user is currently logged in, it still redirects to the /login page because the auth guard that I have setup, checks if the user is logged in.

I have an auth service setup that does all the authentication checks.

In my auth service constructor, that's where I have my onAuthStateChanged code setup:

constructor(
    private auth: AngularFireAuth,
    private router:Router,
    private db:AngularFireDatabase,
  ) {

    firebase.auth().onAuthStateChanged(function(user) {
     if (user) {
       // What do I need to put here to ensure that the auth guard goes to the intended route?
     }
    });

  }

Here is my auth guard's canActivate() method:

 canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean> {

      if(this.authService.getAuthenticated()) {
        return Observable.of(true);
      } else {
        this.router.navigate(['/login']);
      }
    }

And here is the getAuthenticated() method:

getAuthenticated() {
    return firebase.auth().currentUser;
  }

Update:

Here are the methods that are called when the user actually logs in. In the actual component, here is the login method:

login(data, isValid) {
    if(isValid) {

      this.authService.login(data.email, data.password)
          .then(
              (data) => {
                console.log('data', data);
                this.router.navigate(['/projects'])
              }, error => {
                this._utilities.createToasty({
                  msg: "The email/password combination is incorrect.",
                  type: "error"
                });
              }
          );
    }
  }

And in the auth service, here's the login method:

login(email, password) {
    return firebase.auth().signInWithEmailAndPassword(email, password);
  }

So right now, I'm not entirely sure what code I need to put where to ensure that when my user refreshes the page, the auth guard picks up on that and actually allows the user to go to the route instead of always redirecting to the /login route.

Thoughts?

5 Answers
firebase.auth().onAuthStateChanged(function (user) {
   console.log('onAuthStateChanged: ', user);
});

Let me try to solve this by saving user data in local storage. My logic is pretty straightforward when the user is logged in we will save the user data in local storage, by doing this we'll have the user state even after the page is reloaded.

userData: any;

constructor(
    public afAuth: AngularFireAuth
) {    
    this.afAuth.authState.subscribe(user => {
      if (user) {
        localStorage.setItem('user', JSON.stringify(this.userData));
        JSON.parse(localStorage.getItem('user'));
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    })
  }

Write your code inside setTimeout. Because this problem happens after refreshing page.

setTimeout(()=>{
console.log("currentUser", firebase.auth().currentUser);
},1000)
Related