簡體   English   中英

Angular 在使用 firebase 的身份驗證系統中總是返回 undefined 或 null

[英]Angular always returning undefined or null in authentication system with firebase

我建立與驗證系統, email and passwordfirebase登錄和退出都工作得不錯的響應console.log(authState)angular guard總是返回方法isLoggedIn()null ,我不知道這是為什么? ! 在構造函數中,我用 userDetails 值定義了它:

僅用於 auth.service 構造函數的代碼:

  public user: Observable<firebase.User>;
  public userDetails: firebase.User = null;


  constructor(
    private af: AngularFireAuth,
    private navCtrl: NavController,
    private statusMessage: ToastMessagesService
  ) {


    this.user = af.authState;

    this.user.subscribe(
      user => {
        this.userDetails = user;
        console.log(this.userDetails); // I get a response from this on the login page with user details ( user is logged in )
      }
    )

  }

單獨方法的代碼:

  isLoggedIn(): boolean {
    return (this.userDetails != null) ? true : false;
  }

整個服務的代碼( auth.service.ts ):

import { Injectable } from '@angular/core';
import { AngularFireAuth } from 'angularfire2/auth';
import { Observable } from 'rxjs/internal/observable';
import { NavController } from '@ionic/angular';
import { ToastMessagesService } from './toast-messages.service';
import * as firebase from 'firebase';

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  public user: Observable<firebase.User>;
  public userDetails: firebase.User = null;


  constructor(
    private af: AngularFireAuth,
    private navCtrl: NavController,
    private statusMessage: ToastMessagesService
  ) {


    this.user = af.authState;

    this.user.subscribe(
      user => {
        this.userDetails = user;
        console.log(this.userDetails); 
      }
    )

  }

  async siginInRegular(username: string, password: string) {
    // const credentials = this.af.auth.email
    const results = await this.af.auth.signInWithEmailAndPassword(username, password).then(
      results => {
        this.navCtrl.navigateForward('/home');
        this.statusMessage.message(`Welcome ${results.user.email}`);
      }
    );

  }

  async register(username: string, password: string) {
    try {
      return await this.af.auth.createUserWithEmailAndPassword(username, password).then(
        user => {
          this.navCtrl.navigateForward('/profile');
          this.statusMessage.message(`Welcome ${user.user.email}`);
        }
      );
    } catch (error) {
      console.dir(error);
    }
  }

  signOut() {
    return this.af.auth.signOut();
  }

  isLoggedIn(): boolean {
    return (this.userDetails != null) ? true : false;
  }



}

守衛的代碼:

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

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {


  constructor(
    private auth: AuthService
  ) {
    console.log(auth.isLoggedIn());

  }

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


    if (this.auth.isLoggedIn()) {
      return true
    }

    console.log('Access denied!');
    return false;
  }
}

您的代碼中可能存在競爭。 this.userDetails中的 this.userDetails 在您從警衛中調用它時還沒有“准備好”。

你可以做的是,在canActivate方法中返回一個 promise/observable,因為它接受Observable<boolean> | Promise<boolean> | boolean Observable<boolean> | Promise<boolean> | boolean Observable<boolean> | Promise<boolean> | boolean

一個基本的例子可能是這樣的:

  1. 在您的身份驗證服務中添加一個獲取身份驗證狀態的方法:

     get authState(): Observable<any> { return this.af.authState; }
  2. 在您的canActivate()方法中使用它:

     canActivate(): Observable<boolean> { return this.authService.authState() .pipe( map(authState => !!authState), tap(auth => !auth ? console.log('Access Denied!') : true), take(1) ); }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM