Firebase Firestore 安全规则共享数据

Posted

技术标签:

【中文标题】Firebase Firestore 安全规则共享数据【英文标题】:Firebase firestore security rules sharing data 【发布时间】:2019-10-10 15:11:14 【问题描述】:

我在 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】:

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

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

【讨论】:

以上是关于Firebase Firestore 安全规则共享数据的主要内容,如果未能解决你的问题,请参考以下文章

匿名身份验证用户的这个 Firebase/Firestore 安全规则是不是安全?

为啥 firebase_firestore 安全规则不适用于文档读取

在不使用 Firebase 身份验证的情况下设置 Firestore 安全规则

Cloud Firestore 安全规则只允许从 Firebase 函数写入

基于引用数据类型的 Firebase Firestore 安全规则

在 Angular 11 网站上使用 Firestore 和 Firebase 存储进行图像上传功能导致来自 Firebase 的不安全规则通知