Firebase Firestore安全规则共享数据

时间:2019-10-10 15:11:14

标签: firebase google-cloud-firestore firebase-security

我在firestore中具有此数据结构,在该结构中,我试图将用户链接到个人资料,然后链接到事件。一个配置文件可以由多个用户共享,并且应该能够访问该配置文件的事件。

user
    - id
    - email
    - name
    - profilePicUrl

profile
    - id
    - name
    - dateOfBirth
    - owners: [ "user1","user2" ]
    - etc.

event
    - id
    - profileId
    - name
    - startDate
    - endDate

我目前有:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{id} {
      allow read, write: if request.auth.uid == id;
    }
    match /profiles/{id} {
        allow read, write: if ("owners" in resource.data && resource.data.owners != null && request.auth.uid in resource.data.owners);
    }
    match /events/{id} {
        allow read, write: if hasAccess(userId, resource) == true;
    }
  }
}

function hasAccess(userId, resource) {
    // Not sure what to put here but basically need
    // to get profiles where user is owner
    // and get events for these profiles
}

但不确定在hasAccess函数中要放什么。感谢有人可以引导我。

更新2019/10/11

我可以通过以下规则使它起作用:

    match /events/{id} {
            allow read, write: if (exists(/databases/$(database)/documents/profiles/$(resource.data.profileId)) && 
                                  "owners" in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data && 
                                  get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners != null && 
                                  request.auth.uid in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners);
        }

更新2019/10/14

我在写入方面存在一些权限问题,因此我必须对其进行修改,如下所示:

match /events/{id} {
  allow read: if ( exists(/databases/$(database)/documents/profiles/$(resource.data.profileId)) 
                     &&   "owners" in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data 
                     &&   get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners != null 
                     &&   request.auth.uid in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners);
  allow write: if ( request.auth.uid in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners );
}

1 个答案:

答案 0 :(得分:0)

鉴于数据的现有结构,使用安全规则实际上是无法实现的。这是由于安全规则无法对集合执行查询。唯一可以做的就是get()使用其已知路径sort来读取其字段,这不会帮助您链接无法建立该路径的文档。

您可以做的是将规则所需的数据复制到每个需要保护的文档中。这意味着每个事件文档都需要在字段中包含每个所有者列表的副本。是的,如果必须更改事件的所有者列表,那么使所有事件保持最新状态将更加麻烦。