首页 > 解决方案 > 当前用户设置为空,即使已登录

问题描述

我创建了身份验证服务

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { User } from 'firebase';


@Injectable({
  providedIn: 'root'
})
export class AuthService {
  user: User;

  constructor(public afAuth: AngularFireAuth) {
    this.afAuth.authState.subscribe(user => {
      if (user) {
        this.user = user;
        localStorage.setItem('user', JSON.stringify(this.user));
      } else {
        localStorage.setItem('user', null);
      }
    });
  }

  async register(email: string, password: string, displayName: string) {
    await this.afAuth.auth.createUserWithEmailAndPassword(email, password);

    await this.user.updateProfile({ displayName });

    this.user.sendEmailVerification();

    return this.user.uid;
  }

用户成功注册后,我可以访问用户属性并调用 updateProfile 函数。

但我也想使用此服务来更新个人资料信息,例如:电子邮件或电话,但每当我这样做时,我都会将用户设置为空。

标签: angularfirebasefirebase-authentication

解决方案


那是因为user起初是null. 您可能希望按如下方式更改构造函数:

constructor(public afAuth: AngularFireAuth) {
    this.user = localStorage.getItem('user'); // <-- Added this line
    this.afAuth.authState.subscribe(user => {
      if (user) {
        this.user = user;
        localStorage.setItem('user', JSON.stringify(this.user));
      } else {
        localStorage.setItem('user', null);
      }
    });
  }

您可能想阅读它:

我假设您在尝试从AuthService.user. 这是意料之中的。

AuthService.user起初为null,在firebase成功响应后,您将其设置userFirebaseUser对象。

在不同的地方,您正在尝试获取user. 但问题是你获取它太快了。意思是,当它仍然为空时,您正在获取user(因为 firebase 尚未返回任何值)。

为了修复它,您需要将您的设置user为 Observable:

export class AuthService {
  user$: Observable<User>;

  constructor(public afAuth: AngularFireAuth) {
    this.user$ = new Observable(localStorage.getItem('user')).pipe(
      switchMap((fromLocal) => this.afAuth.authState),
      tap((user) => localStorage.setItem('user', JSON.stringify(user)))
    );
  }

在不同的班级:

  authService.user$.subscribe(user => /** user: User **/); // Don't forget to unsubscribe

或在 HTML 模板中(注意async管道):

  <ng-container *ngIf="authService.user$ | async as user">
    <!-- user: User -->
  </ng-container>

并在您的注册表中更改为:

  async register(email: string, password: string, displayName: string) {
    await this.afAuth.auth.createUserWithEmailAndPassword(email, password);

    return this.user$.pipe(
      first(),
      tap((user) => user.updateProfile({ displayName }),
      tap((user) => user.sendEmailVerification()),
      map((user) => user.uid)
    ).toPromise();
  }

PS:

为可观察实例添加$后缀是惯例(例如user -> user$)。


推荐阅读