Angular Firebase ngIf用户已通过身份验证';无法重新加载页面

Angular Firebase ngIf用户已通过身份验证';无法重新加载页面,angular,firebase,observable,angularfire2,angular2-observables,Angular,Firebase,Observable,Angularfire2,Angular2 Observables,我正在使用来自firebase的onAuthStateChanged来侦听用户的身份验证状态。我正在收听导航组件中的这些更改,以决定是否显示登录按钮或注销按钮等 如果我在应用程序中导航,这很好,但是当我刷新页面时,DOM会反映用户的状态,即使订阅被触发 可能是我忽略了一个简单的修复方法,但是我还没有找到一个在我的研究中有效的修复方法,并且已经投入了太多的时间-请帮助 这是我的授权服务: private authStatusSub = new Subject(); user$ = this

我正在使用来自firebase的onAuthStateChanged来侦听用户的身份验证状态。我正在收听导航组件中的这些更改,以决定是否显示登录按钮或注销按钮等

如果我在应用程序中导航,这很好,但是当我刷新页面时,DOM会反映用户的状态,即使订阅被触发

可能是我忽略了一个简单的修复方法,但是我还没有找到一个在我的研究中有效的修复方法,并且已经投入了太多的时间-请帮助

这是我的授权服务:

  private authStatusSub = new Subject();
  user$ = this.authStatusSub.asObservable();

  setAuthStatusListener() {
    this.auth.onAuthStateChanged((user) => {
      if (user) {
        this.usersService
          .getUserData(user.uid)
          .then((userData) => {
            this.authStatusSub.next(userData);
          })
          .catch((err) => {
            console.log(err);
          });
      } else {
        this.authStatusSub.next(null);
        console.log('User has logged out');
      }
    });
  }
导航类型脚本文件:

  isAuthenticated: boolean;

  ngOnInit() {
    this.authService.setAuthStatusListener();
    this.authService.user$.subscribe((userData) => {
      if (userData) {
        this.isAuthenticated = true;
        console.log(userData);
      } else {
        this.isAuthenticated = false;
      }
    });
  }
导航html:

  <a routerLink="/login" *ngIf="!isAuthenticated" mat-button class="navButton">Login</a>
  <a mat-button *ngIf="isAuthenticated" class="navButton" (click)="onLogout()">Logout</a>
登录
注销
当我通过正常的应用程序流程登录、注销并导航到主页(导航栏所在的位置)时,它会按预期工作,但当我刷新主页(导航栏所在的位置)时,状态不会反映在DOM中。即使没有反映状态,nav typescript文件中的console.log()也会使用正确的数据触发,因此我知道observable正在工作


非常感谢您的帮助

由于您使用的是
AngularFireAuth
,因此您可以像这样简化您的服务:

服务:

  • 摆脱主题(
    authStatusSub
  • 直接从
    AngularFireAuth.authState
  • 不要订阅服务
因此,代码可以如下所示:

服务:

constructor(private fireAuth: AngularFireAuth) { }

user$ = this.fireAuth.authState;
导航组件:

this.authService.user$.subscribe(
    userData => this.isAuthenticated = !!userData
);

可能是
authService.user$
在订阅发生之前发出。您可以尝试使用
ReplaySubject(1)
而不是普通的Subject,以确保在订阅延迟时获得以前发出的值。在
ngOnInit
中,您可以尝试将调用放到
this.authService.setAuthStatusListener()结尾。但是,您似乎可以大大简化代码,因为您已经在使用
AngularFireAuth
,因为它已经提供了
authState
作为可观察对象,所以您不需要主题。我尝试在订阅后放置setAuthStatusListener(),但没有成功:(我对ReplaySubject不熟悉,我会查一下的是的,我只是不想在任何其他组件中有任何auth逻辑,但我想它不会比我的工作方式更混乱,谢谢!!!