【问题标题】:How to make a query that retrieve a collection and a subcollection in firebase with angularfire?如何使用angularfire进行查询以检索firebase中的集合和子集合?
【发布时间】:2021-10-26 12:56:47
【问题描述】:

我的 firebase 数据库中有以下结构:

/profiles/{uid}/displayName
               /email
               /otherAttribues
               /roles/{roleName}/someAttribute
                                /someOtherAttribute

所以“角色”是一个子集合,主要是因为它必须具有与配置文件的其余部分不同的写入权限。

在我的组件中,我目前正在检索配置文件:

  constructor(private firestore: AngularFirestore) {
    this.users$ = this.firestore.collection<User>('profiles').valueChanges();
  }

在我的 html 中,我在 *ngFor 循环中使用此 users$ 在网格中显示配置文件。我需要添加一列,该列将根据 ID 为“admin”或“user”的角色的存在/不存在来显示。这可以从其他用户修改,所以它必须是可观察的。

如何检索我的个人资料的“角色”(至少是子集合中文档的 ID)并仍然很好地对其进行迭代?

这可以改变,所以我需要它是一个可观察的。我找不到在我的请求中“包含”子集合的方法。

根据角色,我需要有

【问题讨论】:

    标签: javascript angular firebase google-cloud-firestore angularfire2


    【解决方案1】:

    Firestore 读取很浅,它们仅从您命名的集合(组)中读取,因此在您的情况下从 user 读取。无法在同一操作中同时从子集合中读取。

    关于用户角色的信息有两个常用选项:

    1. 对每个单独的用户执行额外的读取操作,或者一次性对所有 roles 集合执行 collection group query
    2. roles的相关信息复制到user的父文档中。

    鉴于您的查询要求非常简单,我可能会选择(也)将信息存储在 user 文档中,或者直接从客户端,或者通过每当roles 数据触发的云函数已更新。

    【讨论】:

    • 1.如何进行组查询以将每个对象与子集合合并? 2. 我不能复制,他们没有相同的写权限,所以这意味着用户可以提升自己的某些功能管理员
    • 2) 您可以拒绝对安全规则中特定字段的更改。 1)我不确定我是否理解。如果您想知道如何确定某个角色文档属于哪个用户文档,那就是遵循parent 属性链向上类似于我在这里为 Flutter 展示的内容:stackoverflow.com/a/61713774
    • 嗨@Frank,谢谢你的回答,但我必须承认你的回答并不是很有用,因为它在不同的集合中,很明显这需要额外的需求,我只是不知道如何使用 map/tap/switchmap/combineLatest 运算符来做到这一点。 RXJS 世界有点新,我更习惯 async/await 模式
    【解决方案2】:

    我在我的用户组件中完成了以下操作:

    this.users$ = this.firestore.collection<User>('profiles').valueChanges({ idField: 'uid' }).pipe(
          switchMap((profiles) => {
            const res = profiles.map(profile => {
              return this.firestore.collection(`profiles/${profile.uid}/roles`).valueChanges({ idField: 'Id' }).pipe(
                map(doc => {
                  return doc.map(d => d.Id)
                }),
                tap(roles => {
                  //TODO: consolidate the profile with the roles here
                  //This will be updated on changes
                }),
                map(roles => Object.assign(profile, { roles }))
              );
            })
            return combineLatest(...res);
          })
        );
    

    注意:它警告我不要使用 combineLatest,但不知道如何替换它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-17
      • 2019-03-27
      • 2019-12-20
      • 2018-12-13
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 1970-01-01
      相关资源
      最近更新 更多