使用 AngularFire2 v4 检查身份验证状态

Checking authentication state with AngularFire2 v4

我正在尝试在服务上封装 AngularFire2 v4 身份验证状态 class 所以我只有一种方法来检查用户是否已通过身份验证。

我正在按照 v4 升级指南进行操作:https://github.com/angular/angularfire2/blob/master/docs/version-4-upgrade.md

这是我服务的相关部分class:

export class AuthService {

  user: Observable<firebase.User>;

  constructor(
    private angularFireAuth: AngularFireAuth,
  ) {
    this.user = this.angularFireAuth.authState;
  }

  get isAuthenticated(): boolean {
    let authenticated = false;
    this.user.take(1).subscribe(user => authenticated = user !== null);
    return authenticated;
  }

}

我遇到的问题是 authenticated 总是 returns false,即使 user 不为空。我做错了什么?

它返回 false 因为 subscribe 中的回调将在可观察对象中有要读取的值时同步调用,或者在没有要读取的值时异步调用。在你的情况下没有,所以你实际上是在不等待这些值的情况下返回初始 false

你可以这样做:

get isAuthenticated(): Observable<boolean> {
    return this.user.last().map(user => user !== null);
}

现在,要在您的模板中使用 getter,您应该使用 async 管道。类似于:*ngIf="(isAuthenticated | async)".

请注意,我还将 .take(1) 更改为 .last(),我认为这里更有意义。

为了准确展示这里发生的事情。

Observable 被同步调用:

const source = Rx.Observable.range(0, 2);

function isAuthenticated() {
  let authenticated = false;
  
  source.last().subscribe((x) => {
    console.log('New value: ' + x);
        
    authenticated = true;
  });
    
  return authenticated;
}

console.log(isAuthenticated())
console.log(isAuthenticated())
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.js"></script>

Observable 被异步调用:

const source = Rx.Observable.range(0, 2).delay(1000);

function isAuthenticated() {
  let authenticated = false;
  
  source.last().subscribe((x) => {
    console.log('New value: ' + x);
        
    authenticated = true;
  });
    
  return authenticated;
}

console.log(isAuthenticated())
console.log(isAuthenticated())
<script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.js"></script>