我想要实现的目标:我想使用BehaviorSubject在我的应用程序中共享身份验证状态。我使用身份验证状态,例如在auth-guard内部,以防止用户在用户已经过身份验证时访问登录/注册页面。
问题:因为BehaviorSubject有一个初始值,该值为false(未登录),似乎auth-guard取了第一个值,而不是等待uid-sync。
AuthInfo (Auth状态存储):
export class AuthInfo {
constructor(public uid: string) {}
isLoggedIn() {
return !!this.uid;
}
}
AuthService :
@Injectable()
export class AuthService {
static UNKNOWN_USER = new AuthInfo(null);
authInfo$: BehaviorSubject<AuthInfo> = new BehaviorSubject<AuthInfo>(AuthService.UNKNOWN_USER);
constructor(private af: AngularFire) {
this.af.auth.subscribe(auth => {
if (auth) {
console.log('got the uid');
this.authInfo$.next(new AuthInfo(auth.uid));
} else {
this.authInfo$.next(AuthService.UNKNOWN_USER);
}
});
}
logIn(email: string, password: string): Promise<FirebaseAuthState> {
return this.af.auth.login({email: email, password: password});
}
}
AuthGuard :
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService,
private router: Router) {
}
canActivate(): Observable<boolean> {
return this.authService.authInfo$.map(authInfo => {
if (authInfo.isLoggedIn()) {
this.router.navigate(['/user'])
}
return !authInfo.isLoggedIn();
});
}
}
因此,当authInfo.isLoggedIn()
为false
时,canActivate会被处理,在一小段时间后,我会在控制台中看到Got the uid
。任何想法如何防止第一个false
?我认为这里正确使用BehaviorSubject,因为它允许我们设置初始状态。但是,auth-guard将始终收到false(初始值)。在那之后
this.authInfo$.next(new AuthInfo(auth.uid));
当canActivate方法已经完成时,将触发。