Firebase Firestore数据建模以获取用户有权从集合中访问的未知数量的文档

Firebase Firestore数据建模以获取用户有权从集合中访问的未知数量的文档,firebase,google-cloud-firestore,Firebase,Google Cloud Firestore,我想要的是能够发送一个查询,返回用户所在的所有团队。uid1将返回团队1,但不会返回其他团队。我当前的模型不起作用,因为我只是遇到权限问题,因为用户没有读取团队集合中所有文档的权限 团队集合可以包含多个团队,用户可以是多个团队的一部分 以下是我当前firestore的组织方式: Users: uid1 firstname: xxxx lastname: yyyy Teams: team1 subCollection1

我想要的是能够发送一个查询,返回用户所在的所有团队。uid1将返回团队1,但不会返回其他团队。我当前的模型不起作用,因为我只是遇到权限问题,因为用户没有读取团队集合中所有文档的权限

团队集合可以包含多个团队,用户可以是多个团队的一部分

以下是我当前firestore的组织方式:

Users:
    uid1
        firstname: xxxx
        lastname: yyyy
Teams:
     team1
         subCollection1
             ...
         subCollection2
             ...
         members
             uid1
             ...
         roles
             uid1
                 role: dev
    team2
        ...
我只想到了两种解决办法,但似乎都不是很好

  • 在用户集合中的每个用户下都有一个列表/子集合,其中包含用户所在的所有团队
  • 在包含团队成员所有uid的团队集合中的每个文档中都有一个数组类型的字段。(然后使用.where(“成员”,“数组包含”,uid))

  • 组织数据以实现我想要的功能的最佳方式是什么?

    您可以在用户下创建一个子集合,并执行
    collectionGroup
    查询以获取该团队中的所有用户,或者执行常规查询以获取用户所在的所有团队。您只需将teamID存储在子集合中,如果需要,还可以存储一些其他静态信息

    Users:
        uid1
            firstname: xxxx
            lastname: yyyy
            teams (collection)
                 teamID (document)
                 teamID (document)
        uid2
            firstname: xxxx
            lastname: yyyy
            teams (collection)
                 teamID (document)
    Teams:
         team1
             subCollection1
                 ...
             subCollection2
                 ...
             roles
                 uid1
                     role: dev
          team2
              ...
    
    现在也不需要将
    成员
    存储在
    团队
    下,因为您可以通过
    用户
    集合运行所有查询,并且一旦拥有
    团队ID
    ,您就可以用它做任何事情

    您还必须更改
    collectionGroup
    查询的权限才能使其工作

    例如:

    rules_version = '2';
    service cloud.firestore {
    
      match /databases/{database}/documents {
    
        match /{path=**}/teams/{teamID} {
    
          allow read: if request.auth.uid != null;
    
        }
    
        match /users/{userID}/teams/{teamID} {
    
          allow write: if request.auth.uid == resource.data.author;
    
        }
      }
    }
    

    您可以在用户下创建一个子集合,并执行
    collectionGroup
    查询以获取该团队中的所有用户,或者执行常规查询以获取用户所在的所有团队。您只需将teamID存储在子集合中,如果需要,还可以存储一些其他静态信息

    Users:
        uid1
            firstname: xxxx
            lastname: yyyy
            teams (collection)
                 teamID (document)
                 teamID (document)
        uid2
            firstname: xxxx
            lastname: yyyy
            teams (collection)
                 teamID (document)
    Teams:
         team1
             subCollection1
                 ...
             subCollection2
                 ...
             roles
                 uid1
                     role: dev
          team2
              ...
    
    现在也不需要将
    成员
    存储在
    团队
    下,因为您可以通过
    用户
    集合运行所有查询,并且一旦拥有
    团队ID
    ,您就可以用它做任何事情

    您还必须更改
    collectionGroup
    查询的权限才能使其工作

    例如:

    rules_version = '2';
    service cloud.firestore {
    
      match /databases/{database}/documents {
    
        match /{path=**}/teams/{teamID} {
    
          allow read: if request.auth.uid != null;
    
        }
    
        match /users/{userID}/teams/{teamID} {
    
          allow write: if request.auth.uid == resource.data.author;
    
        }
      }
    }
    

    请添加数据库的屏幕截图,而不是描述数据库的外观。请添加数据库的屏幕截图,而不是描述数据库的外观。谢谢,但我如何编写安全规则,以便只有团队成员才能读取团队成员。我尝试了
    match/{path=**}/teams/{team}{allow read:if exists(/databases/$(database)/documents/users/$(request.auth.uid)/teams/$(team));}
    但它似乎不起作用,因为我得到了拒绝权限的错误。谢谢,但是我该如何编写安全规则,以便只有团队成员才能读取团队成员是谁呢。我尝试了
    match/{path=**}/teams/{team}{allow read:if exists(/databases/$(database)/documents/users/$(request.auth.uid)/teams/$(team));}
    但它似乎不起作用,因为我遇到了权限被拒绝的错误。