【问题标题】:Firestore Database Rules and Structure for sharing Documents between users用于在用户之间共享文档的 Firestore 数据库规则和结构
【发布时间】:2018-03-19 18:37:35
【问题描述】:

我正在尝试创建一个允许用户在列表上进行协作的应用程序。每个用户都需要被邀请才能在列表上工作。

我是这样构建数据的(大致基于this blog post)。 如果需要,也可以更改此结构。

list
  list_1:
    users:
      owner:
        owner@company.com: true
      shared:
        user@company.com: true
        user2@company.com: true
    id
    name
    items:
      item_1:
        id:
        name:
      ...

我想要实现的目标:每个人都应该能够创建列表。他们的创建者然后成为创建列表的所有者。 只有“共享”文档中的所有者和用户才能读取和写入此列表。

我猜权限设置应该是这样的。但这不起作用:

service cloud.firestore {
  match /databases/{database}/documents {
    match /lists/{listId}/{anything=**} {
        allow read, write: if !exists(resource.data.users.owner) ||
                               resource.data.users.owner == request.auth.token.email ||
                               request.auth.token.email in resource.data.users.shared
    }
  }
}

【问题讨论】:

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


    【解决方案1】:

    我想通了。

    我把数据结构改成这样:

    list
      list_1
        owner: owner@company.com
        writeAccess: [user1@company.com, user2@company.com]
        id
        name
        items:
          item_1:
            id:
            name:
          ...
    

    那么这样的数据库规则就起作用了:

    service cloud.firestore {
      match /databases/{database}/documents {
        match /lists/{listId} {
            // Allow RW on lists for owner, shared user or for everyone if it's a new list
          allow read, write: if resource.data.owner == request.auth.token.email ||
                                request.auth.token.email in resource.data.writeAccess ||
                                !exists(/databases/$(database)/documents/lists/$(listId))
        }
        match /lists/{listId}/items/{itemId} {
            // Allow RW on item for owner or shared user of parent list
            allow read, write: if get(/databases/$(database)/documents/lists/$(listId)).data.owner == request.auth.token.email ||
                                  request.auth.token.email in get(/databases/$(database)/documents/lists/$(listId)).data.writeAccess ||
                                 !exists(/databases/$(database)/documents/lists/$(listId)) // Needed for new lists. Because lists and items are created in a batch
        }
      }
    }
    

    【讨论】:

    • 如果您使用这样的写访问列表进行共享,那么您如何查询一个用户的所有列表?在这里,他们说如果您使用数组,则不可能获得所有类别为猫的帖子:firebase.google.com/docs/firestore/solutions/arrays。你是怎么解决的?
    • @TheOddler 没错,使用此解决方案无法查询一个用户的所有列表。为了使这成为可能,您可以将用户的 id 存储为映射键。这也是您发布的链接中的建议。不幸的是,点不允许作为映射键。所以电子邮件地址不起作用。基于地图的权限也存在一个已知问题。见:stackoverflow.com/q/46674372/2837489
    • 感谢您的回答!所以这就解释了为什么它不起作用。虽然我在地图中使用了uid,但仍然没有蛋糕。感谢您的链接!现在,我将对允许的测试人员进行硬编码,并留意更新。
    • @MarcelBochtler 你有关于“不允许点作为映射键”的文档的链接吗?
    • @MarcelBochtler 实际上可以使用电子邮件地址作为键,通过使用new firebase.firestore.FieldPath()where() 查询中构建路径。 firebase.google.com/docs/reference/js/…
    猜你喜欢
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    相关资源
    最近更新 更多