刷新页面时返回未定义的 Firebase 查询函数

Firebase query function returning undefined when page is refreshed

我在 Angular 中获得了一项从 firestore 获取用户数据的服务。相关服务代码如下:

userType:string = ''

async getProfileType(): Promise<string> {
    const userUID = await this.getUserUID();

    const getUserType = () => {
      this.af
        .collection('users')
        .doc(userUID)
        .valueChanges()
        .subscribe((doc: any) => {
          console.log(doc.userType);
          this.userType = doc.userType;
        });

      return this.userType;
    };
    return getUserType();
  }

当我尝试通过注入它并在 ngOnInit 方法中调用函数来在组件中调用它时,出现以下错误: ERROR TypeError: Cannot read properties of undefined (reading 'userType')

当我从服务中手动调用该函数时,它 returns 数据很好,但我不确定为什么在 ngOnInit 方法上调用时它不能做同样的事情。

我试过使 ngOnInit 异步并在 getProfileType 函数上使用 await 但这似乎没有什么不同。

组件TypeScript如下:

import { Component, OnInit } from '@angular/core';
import { AngularFirestore } from '@angular/fire/compat/firestore';
import { UserInfoService } from '../services/user-info/user-info.service';

@Component({
  selector: 'app-edit-profiles',
  templateUrl: './edit-profiles.component.html',
  styleUrls: ['./edit-profiles.component.scss'],
})
export class EditProfilesComponent implements OnInit {
  constructor(public userInfo: UserInfoService, private af: AngularFirestore) {}

  async ngOnInit() {
    this.userInfo.getProfileType();
  }

组件HTML如下:

<div *ngIf="userInfo.userType === 'user'">
  You're a User
</div>
<div *ngIf="userInfo.userType === 'project'">
  You're a Project
</div>
<button mat-flat-button (click)="userInfo.getProfileType()">Get Profile Type</button>

感谢任何帮助或指导,干杯!

您的 getProfileType 方法声称是 returning 一个 Promise<string>,但它实际上只是 returning 一个尚未初始化的 string然而,因为您永远不会等待数据库结果。

async getProfileType(): Promise<string> {

我建议 returning Observable<string>,因为配置文件类型可能会更改:

getProfileType(): Observable<string> {
  const userUID = await this.getUserUID();

  return this.af
    .collection('users')
    .doc(userUID)
    .valueChanges()
    .pipe(map((doc: any) => {
      return doc.userType;
    }));
}

或者,您可以坚持使用 Promise 方法,但是 return 只有一个文档 take(1)first():

getProfileType(): Observable<string> {
  const userUID = await this.getUserUID();

  return this.af
    .collection('users')
    .doc(userUID)
    .valueChanges()
    .pipe(take(1))
    .pipe((doc: any) => {
      return doc.userType;
    });
}