Angular 菜单8中的用户登录/注销按钮未更新

Angular 菜单8中的用户登录/注销按钮未更新,angular,authentication,menu,page-refresh,Angular,Authentication,Menu,Page Refresh,我有一个mat工具栏,带有登录/注销按钮,网站用户可以随时登录或注销。我有一个身份验证服务,它使用*ngIf=“!(authService.user$| async)创建一个可观察的用户数据用于登录按钮。但这不起作用,除非我手动刷新整个页面。这是为什么?人们会怎么做?我认为在这些情况下,可观察的方法实际上会起作用,但显然我遗漏了一些东西 我还尝试在app.component.ts中以user的身份订阅Observable,并在模板中使用user,但这似乎没有帮助。我知道关于用户使用Observa

我有一个
mat工具栏
,带有登录/注销按钮,网站用户可以随时登录或注销。我有一个身份验证服务,它使用
*ngIf=“!(authService.user$| async)创建一个可观察的用户数据
用于登录按钮。但这不起作用,除非我手动刷新整个页面。这是为什么?人们会怎么做?我认为在这些情况下,可观察的方法实际上会起作用,但显然我遗漏了一些东西

我还尝试在app.component.ts中以
user
的身份订阅Observable,并在模板中使用
user
,但这似乎没有帮助。我知道关于用户使用Observable登录和刷新有几个问题,但他们没有让我理解为什么不这样做工作

我也许应该补充一点,我使用的是一个界面
用户
属性
角色
,用于基于角色的授权,因此它与
firebase.User
不同

authentication.service.ts的相关部分

@Injectable({
  providedIn: 'root'
})

export class AuthenticationService {
  user$: Observable<User>;
  viewAllUser: Boolean = false;

  constructor(
    private afAuth: AngularFireAuth,
    private afs: AngularFirestore,
    private router: Router) {

    this.user$ = this.afAuth.authState.pipe(
      switchMap(user => {
        if (user) {
          return this.afs.doc<User>(`Users/${user.uid}`).valueChanges()
        } else {
          return of(null)
        }
      }))
  }

  /* Sign up */
  SignUp(email: string, password: string) {
    this.afAuth.auth.createUserWithEmailAndPassword(email, password)
      .then((result) => {
        window.alert("You have been successfully registered!");
        this.updateUserData(result.user)
        //console.log(result.user);
      }).catch((error) => {
        window.alert(error.message);
        //console.log(error.user);
      });
  }

  /* Sign in */
  SignIn(email: string, password: string) {
    return this.afAuth.auth.signInWithEmailAndPassword(email, password)
      .then((result) => {
        window.alert("You have been successfully signed in!");
        this.updateUserData(result.user);
        //console.log(result.user);
      }).catch((error) => {
        window.alert(error.message);
        //console.log(error.user);
      });
  }

  /* Sign out */
  SignOut() {
    this.router.navigate(['user-main']);
    this.afAuth.auth.signOut();
    window.alert("You have been successfully signed out!");
  }

 private updateUserData(user) {
        // Sets user data to firestore on login
        const userRef: AngularFirestoreDocument<any> = this.afs.doc(`Users/${user.uid}`);
        const data: User = {
          uid: user.uid,
          email: user.email,
          roles: {
            role1: true //default role
          }
        }
        return userRef.set(data, { merge: true }) //Update in non-destructive way 
      }
}

您应该为用户使用
BehaviorSubject
,并像以下那样使用它:

authentication.service.ts:

    private currentUserSubject = new BehaviorSubject<User>({} as User);
    public currentUser = this.currentUserSubject.asObservable().pipe(distinctUntilChanged());

  getCurrentUser(): User {
    return this.currentUserSubject.value;
  }
      /* Sign up */
      SignUp(email: string, password: string) {
        this.afAuth.auth.createUserWithEmailAndPassword(email, password)
          .then((result) => {
            window.alert("You have been successfully registered!");
            this.updateUserData(result.user);
            //console.log(result.user);
          }).catch((error) => {
            window.alert(error.message);
            //console.log(error.user);
          });
      }

      /* Sign in */
      SignIn(email: string, password: string) {
        return this.afAuth.auth.signInWithEmailAndPassword(email, password)
          .then((result) => {
            window.alert("You have been successfully signed in!");
            this.updateUserData(result.user);
            //console.log(result.user);
          }).catch((error) => {
            window.alert(error.message);
            //console.log(error.user);
          });
      }


      private updateUserData(user) {
        // Sets user data to firestore on login
        const userRef: AngularFirestoreDocument<any> = this.afs.doc(`Users/${user.uid}`);
        const data: User = {
          uid: user.uid,
          email: user.email,
          roles: {
            role1: true //default role
          }
        }
        this.currentUserSubject.next(data); // --> here
        return userRef.set(data, { merge: true }) //Update in non-destructive way 
      }
}
const user = this.authService.getCurrentUser();
if (user.id) {
   return true;
} else {
   return false;
}
auth-guard.service.ts:

    private currentUserSubject = new BehaviorSubject<User>({} as User);
    public currentUser = this.currentUserSubject.asObservable().pipe(distinctUntilChanged());

  getCurrentUser(): User {
    return this.currentUserSubject.value;
  }
      /* Sign up */
      SignUp(email: string, password: string) {
        this.afAuth.auth.createUserWithEmailAndPassword(email, password)
          .then((result) => {
            window.alert("You have been successfully registered!");
            this.updateUserData(result.user);
            //console.log(result.user);
          }).catch((error) => {
            window.alert(error.message);
            //console.log(error.user);
          });
      }

      /* Sign in */
      SignIn(email: string, password: string) {
        return this.afAuth.auth.signInWithEmailAndPassword(email, password)
          .then((result) => {
            window.alert("You have been successfully signed in!");
            this.updateUserData(result.user);
            //console.log(result.user);
          }).catch((error) => {
            window.alert(error.message);
            //console.log(error.user);
          });
      }


      private updateUserData(user) {
        // Sets user data to firestore on login
        const userRef: AngularFirestoreDocument<any> = this.afs.doc(`Users/${user.uid}`);
        const data: User = {
          uid: user.uid,
          email: user.email,
          roles: {
            role1: true //default role
          }
        }
        this.currentUserSubject.next(data); // --> here
        return userRef.set(data, { merge: true }) //Update in non-destructive way 
      }
}
const user = this.authService.getCurrentUser();
if (user.id) {
   return true;
} else {
   return false;
}

感谢您提供的详细信息!我在
this.currentUserSubject.next(result.user)处出错
由于我没有使用
firebase.User
作为
User
,而是制作了自己的界面
User
,其中包括属性
角色
。Atm我想不出一个好办法来解决这个问题…如果你不发布错误详细信息,我就无法理解你的问题。也许你需要把这个放进去。currentUserSubject.next(result.user);如果将模型映射到updateUserData()方法中?当然。“类型为'firebase.user'的参数不能分配给类型为'import(“[PATH]/shared/user”).user”的参数。”。类型“firebase.User”中缺少属性“roles”,但类型“import(“[PATH]/shared/User”).User”中需要属性“roles”。“哦,哇,非常感谢!这就成功了!(顺便说一句,我意识到我还需要在SignOut()方法中添加一些内容:
This.currentUserSubject.next(null);
)如果你不介意的话,还有一个问题。我正在使用一个带有canActivate方法的guard。我应该在那里使用Observable
currentUser
,还是使用Behavior Subject
currentUserSubject
?除了我觉得奇怪的页面刷新后的Behavior Subject之外,我似乎无法让它们中的任何一个正常工作。。。
const user = this.authService.getCurrentUser();
if (user.id) {
   return true;
} else {
   return false;
}