【问题标题】:Get certain documents from collection in Firestore by a field通过字段从 Firestore 中的集合中获取某些文档
【发布时间】:2019-03-16 18:14:49
【问题描述】:

我正在使用 Angular 6 和 angularfire2 做一个 Web 应用程序。我正在获取集合中的所有文档,但现在我需要查询这些文档以获取字段为 role.moderator == true 的所有文档。

  private usersCollection: AngularFirestoreCollection<User>;
  users: Observable<UserId[]>;
  moderators: Observable<UserId[]>;

  constructor(
    private afs: AngularFirestore
  ) {
    this.usersCollection = afs.collection<User>(config.collection_users);

    this.users = this.usersCollection.snapshotChanges().pipe(
      map(actions => actions.map(a => {
        const data = a.payload.doc.data() as User;
        const id = a.payload.doc.id;
        return {id, ...data};
      }))
    );

    // Query this.users ?
  }

一个用户的界面是:

export interface User {
  firstName: string;
  lastName: string;
  emailAddress: string;
  roles: Roles;
  officeAssignedId: string;
}

export interface UserId extends User {
  id: string;
}

export interface Roles {
  administrator?: boolean;
  moderator?: boolean;
}

为了让所有用户都担任版主角色,我在做:

getUsersWithModeratorRole() {
    return this.afs.collection<User>(
      config.collection_users,
      ref => ref.where('roles.moderator', '==', true)).snapshotChanges().pipe(
      map(actions => actions.map(a => {
        const data = a.payload.doc.data() as User;
        const id = a.payload.doc.id;
        return {id, ...data};
      }))
    );
  }

问题是:

  1. 我需要在组件内部订阅和取消订阅。
  2. 我觉得我在复制代码,因为我已经有了 文档(this.users),我只需要按字段查询即可。
  3. 我在我的getUsersWithModeratorRole 里面做.take(1).toPromise() 方法但是,只返回一个用户,我需要全部。我以为.take(1) 会抓住一切。

我的目标是查询我已经拥有的集合 (this.users) 以找到所有拥有字段 role.moderator == true 的用户或将 getUsersWithModeratorRole 方法正确转换为 Promise 以获取所有。

【问题讨论】:

  • 我很难理解你在问什么/你想要实现什么,你能改写一下吗?如果您想获取所有具有 role.moderator === true 的用户,并且您已经检索了所有用户,则可以对此用户数组进行过滤。如果您还没有检索到所有用户,并且您想直接从 Firestore 查询所有具有 role.moderator === true 的用户,那么您的 getUsersWithModeratorRole() 方法看起来是正确的。
  • @SnorreDan 您好,感谢您回复我。我不想在组件中订阅和取消订阅。我想将其转换为 Promise,或者由于我已经在服务中拥有 this.users 中的所有文档,我如何在将结果发送到我的组件之前查询 this.users。我的意思是,查询this.users 以仅获取具有字段role.moderator == true 的用户。使用我的getUsersWithModeratorRole 方法,我觉得我在不必要地复制代码。

标签: angular firebase google-cloud-firestore


【解决方案1】:

您可以像这样创建一个在您的服务上返回 Observable 的方法:

getUsersWithModeratorRole(): Observable<UserId[]> {
  return this.users.pipe(
    map(users => users.filter(user => user.roles.moderator === true))
  );
}

或者如果你希望它返回一个承诺,我认为它会是这样的:

getUsersWithModeratorRole(): Promise<UserId[]> {
  return this.users.pipe(
    take(1),
    map(users => users.filter(user => user.roles.moderator === true))
  ).toPromise();
}

【讨论】:

  • 在第二个sn-p中,我认为你有错误,应该是这样的:return this.users.pipe( map(users =&gt; users.filter(user =&gt; user.roles.moderator === true)) ).toPromise();。但是,对我不起作用,该方法一直在运行并且永远不会结束。
  • 第一个 sn-p,Observable,正在工作,但我更喜欢 Promise,希望您能帮助我在 @987654326 的 sn-p 中找到问题@,关于为什么它没有完成并且没有返回数据。
  • 您对错误的看法是正确的,我已经更新了我的答案。我不太熟悉 toPromise() 的工作原理,但是您可以尝试在服务的管道中添加“publishReplay(1)”吗?因此,您需要在第 15 行末尾添加一个逗号,然后使用“publishReplay(1)”添加一个新的第 16 行。
  • 嗨,对我也不起作用。方法永无止境。
  • 我很确定我现在知道问题所在。为了使 toPromise() 工作,Observable 需要完成。我在上面的代码示例中添加了一个“take(1)”以使其完整。
猜你喜欢
  • 2022-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
  • 2018-04-04
  • 2020-07-24
  • 1970-01-01
  • 2019-11-13
相关资源
最近更新 更多