Angular 在使用 firebase 的身份验证系统中总是返回 undefined 或 null
Angular always returning undefined or null in authentication system with firebase
我正在 firebase
中使用 email and password
构建身份验证系统登录和注销都可以正常响应 console.log(authState)
但 angular guard
总是 returns 方法 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
在你的 AuthService 中还不是 "ready" 当你从你的警卫那里调用它时。
你可以做的是,return canActivate
方法中的 promise/observable,因为它接受 Observable<boolean> | Promise<boolean> | boolean
.
一个基本的例子可能是这样的:
在您的授权服务中添加一个获取授权状态的方法:
get authState(): Observable<any> {
return this.af.authState;
}
在您的 canActivate()
方法中使用它:
canActivate(): Observable<boolean> {
return this.authService.authState()
.pipe(
map(authState => !!authState),
tap(auth => !auth ? console.log('Access Denied!') : true),
take(1)
);
}
我正在 firebase
中使用 email and password
构建身份验证系统登录和注销都可以正常响应 console.log(authState)
但 angular guard
总是 returns 方法 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
在你的 AuthService 中还不是 "ready" 当你从你的警卫那里调用它时。
你可以做的是,return canActivate
方法中的 promise/observable,因为它接受 Observable<boolean> | Promise<boolean> | boolean
.
一个基本的例子可能是这样的:
在您的授权服务中添加一个获取授权状态的方法:
get authState(): Observable<any> { return this.af.authState; }
在您的
canActivate()
方法中使用它:canActivate(): Observable<boolean> { return this.authService.authState() .pipe( map(authState => !!authState), tap(auth => !auth ? console.log('Access Denied!') : true), take(1) ); }