angularfire2 auth state on page reload check user

2020-05-06 08:59发布

问题:

I have an angular4 app using angularfire2 and I'm having difficulty in finding out how to check if a user is logged in on page load. I can login and logout without issue, and I've implemented a guard on the router to prevent unauthorised access.

In an example I've found, the guard calls isLoggedIn in my auth service class, and checks if the user (AngularFireAuth) is not null. Since AngularFireAuth is of type Observable its never null so this doesn't work. How can I check if the user is logged in or not for my guard to work correctly?

Here's my auth service class

import { NotificationService } from './notification.service';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Rx';
import * as firebase from 'firebase/app';
import { Injectable } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import { _firebaseAppFactory } from 'angularfire2/firebase.app.module';


@Injectable()
export class AuthService {

  private _user: Observable<firebase.User>;
  private _userDetails: firebase.User;
  private _success: boolean;

  constructor(private _firebaseAuth: AngularFireAuth, private _router: Router, private _notifier: NotificationService) {
    this._user = _firebaseAuth.authState;
    _firebaseAuth.authState.subscribe((user: firebase.User) => {
      console.log(user);
      this._userDetails = user;
    })
  }

  get user() {
    return this._user;
  }

  isLoggedIn() {
    if (this.user == null) {
      return false;
    } else {
      return true;
    }
  }


  login(email: string, password: string) {
    this._notifier.display(false, '');
    this._firebaseAuth.auth.signInWithEmailAndPassword(email, password).then((user: firebase.User) => {
      // if (user.emailVerified) {
      this._userDetails = user;
      this._router.navigate(['dashboard'])
      // }
    }).catch(err => {
      console.log('Something went wrong:', err.message);
      this._notifier.display(true, err.message);
    })
  }

  logout() {
    this._firebaseAuth.auth.signOut()
      .then((res) => {
        this._userDetails = null;
        this._router.navigate(['/login'])
      });
  }

}

Auth Guard File

import { AngularFireAuth } from 'angularfire2/auth';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { AuthService } from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate {

  isLoggedIn$: Observable<boolean>;

  constructor(private _auth: AuthService, private _router: Router, private _firebaseAuth: AngularFireAuth) {
    this.isLoggedIn$ = _auth.isLoggedIn();

    this.isLoggedIn$.subscribe(res => {
      if (res) {
        console.log("is logged in");
      } else {
        console.log("is not logged in");
      }
    });
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

  }
}

回答1:

You can try this code in auth service class

isLoggedIn(): Observable<boolean> {
  return this._firebaseAuth.authState.map((auth) =>  {
        if(auth == null) {
          return false;
        } else {
          return true;
        }
      });
}

and in your component

declare an Observable isLoggedIn$:Observable<boolean>;

and in constructor this.isLoggedIn$ = authService.isLoggedIn();

now you can subscirbe to the observable

this.isLoggedIn$.subscribe(res => {
  if(res){
    console.log('user signed in');
  }else{
    console.log('user not signed in');
  }
});