在注册期间更新配置文件 Angular Firebase

Update Profile During SignUp Angular Firebase

我正在使用 angularfire/firebase 进行 Angular 项目,我正在通过身份验证进行工作。

当用户注册时,调用以下函数:

  signup(email: string, password: string, name: string) {
    return this.fireAuth
      .createUserWithEmailAndPassword(email, password)
      .then((res) => {
        res.user?.updateProfile({
          displayName: name,
        });

        // set vars and local storage
      });
  }

在我的 app.component 中,我有以下订阅来跟踪更改并存储在我的状态管理中(我不认为 StateMgmt 是这里的问题):

ngOnInit() {
  this.fireAuth.authState.user.subscribe((res) => {
  if(res) {
    console.log(res);
    console.log(res.displayName);
    this.store.dispatch(new SetUser(res));
  }
}

当用户注册时,他们在注册时输入的名称是通过 res.user.updateProfile(... 函数设置的,并且由于 authState 发生了变化,app.component 中的订阅打印出一个对象并存储到 SetUser(res) 状态。

console.log()从这里在app状态打印出一个大对象,包括emailuiddisplayName。然后将其存储在我的状态对象中。但是,在 console.log(res.displayName) 上,结果为空,直到我刷新页面触发“自动登录”,其中从 firebase 获取 displayName。

在我看来,我的 signUp() updateProfile 中的 .then((res)... 对象直到用户已更改并存储后才会被触发。

有没有办法让这个 signUp 函数起作用,以便 SetUser(res) 仅在 updateProfile({... 完成并且 displayName 不再为 null 时调度?

来自我的 app.component console.log(res):

{
 "uid": "vbn6TA8vTiLi7J2",
 "displayName": "my name",
 "photoURL": null,
 "email": "email@email.com",
 ...
}

app.componentconsole.log(res.displayName): null

编辑

我发现的另一个有趣的事情是,当我复制 res 并将其打印出来时,displayName 也是空的。

 const r = JSON.parse(JSON.stringify(res));
 console.log(res);
 console.log(r);

console.log(r) 有一个对象,其中 displayName 为空。 console.log(res) 有一个对象,其中 displayName 不为空,并且是传递给 signUp(... 函数的名称。

这可能是 Angular Fire 中的竞争条件,我会确保在更新用户之前完成用户。

async UpdateProfile(displayName: string) {
    const profile = {
       displayName: stored.username,
       photoURL: stored.profile,
       email: stored.email,
    }
    return (await this.afAuth.currentUser).updateProfile(profile);
}

我假设您通过表单对象将用户详细信息存储为 stored 但这很容易来自身份验证提供程序或自定义对象

即使在继续之前通过异步等待等待用户完成也没有用。

我最后做了以下事情:

在我的 signUp() 函数中,创建用户后,我通过 this.fireAuth.authState 检索当前使用(fireAuth 来自我的构造函数中的 AngularFireAuth)。我订阅了这个,同时管道只取第一个值,然后调度我的 SetUser 函数。这确保函数仅在 updateProfile 使用 .then().

完成后才为 运行

因为我将状态调度移到了我的注册函数中,所以我从我的 AppComponent 中删除了订阅。

这是我在身份验证服务中的注册函数:

...

  constructor(
    public fireAuth: AngularFireAuth,
  ) {
    this.user = this.fireAuth.authState;
  }

  signup(email: string, password: string, name: string) {
    return this.fireAuth
      .createUserWithEmailAndPassword(email, password)
      .then((res) => {
        res.user
          ?.updateProfile({
            displayName: name,
          })
          .then(() => {
            this.user.pipe(first()).subscribe((res) => {
              this.store.dispatch(new SetUser(res));
            });
          });
      });
  }