【问题标题】:Firestore security rules with reference fields带有参考字段的 Firestore 安全规则
【发布时间】:2018-09-01 22:46:57
【问题描述】:

我有点卡在这里,因为无法调试这些规则。我会感谢以下规则的帮助。

我想访问:

/modules/module-id/sessions/session-id/parts/

hasCompletedPrerequisiteSession()第一部分与null的比较效果很好,第二部分不行!

路径/modules/moduleId/sessions/sessionId/prerequisite 指向一个引用字段。

service cloud.firestore {
    match /databases/{database}/documents {

      function hasCompletedPrerequisiteSession(moduleId,sessionId) {
                // this part works well                                   
        return getPrerequisiteSession(moduleId,sessionId) == null ||
           // !!! this part does not work !!!
           hasCompleted(getPrerequisiteSession(moduleId,sessionId).id);
      }

      function getPrerequisiteSession(moduleId,sessionId) {
        return get(/databases/$(database)/documents/modules/$(moduleId)/sessions/$(sessionId)).data.prerequisite;
      }

      function hasCompleted(sessionId) {
        return exists(/databases/$(database)/documents/progress/$(request.auth.uid)/sessions/$(sessionId));
      }

      match /modules/{moduleId}/sessions/{sessionId}/parts/{partId} {
        allow read: if hasCompletedPrerequisiteSession(moduleId,sessionId);
      }
    }
  }

(如果我将会话 ID 存储为字符串而不是对会话的引用,则可以正常工作。)

编辑

问题

  1. 安全规则中的引用字段。假设modules/moduleId/owner 指向reference 类型的字段。获取引用文档 id 的正确方法是什么?get(../modules/moduleId).data.owner.data.idget(../modules/moduleId).data.owner 或其他?

【问题讨论】:

  • 谢谢@ToniTornado,这没用。我在上面添加了一个问题。你能回答吗?
  • 我们需要知道您的查询对您没有帮助。在获取数据之前,会根据安全规则对查询进行评估。
  • 我想访问/modules/module-id/sessions/session-id/parts/。顺便说一句,如果我将会话 ID 存储为字符串而不是对会话的引用,它可以正常工作。

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


【解决方案1】:

可能是在getPrerequisiteSession 附近,在使用get 通过引用路径拉取对象后,您必须先使用.data,然后才能引用id 字段。当然id字段需要存储为对象字段。

例如,在我的例子中,我需要允许用户在聊天室中添加消息,前提是他们是该聊天室的所有者。有 2 个“表格” - chatschat_messageschat_messages 通过 chatId 字段与特定聊天相关。 chats 对象具有 ownerId 字段。 我使用的规则是这样的:

    match /chat_messages/{itemId} {
      function isOwner() {
          return get(/databases/$(database)/documents/chats/$(request.resource.data.chatId)).data.ownerId == request.auth.uid;
      }
      
      allow read: if true;
      allow create: if isOwner();
    }

【讨论】:

    【解决方案2】:

    来自 Firebase 支持:

    似乎在您的用例中,您想从参考字段的值(先决条件)中获取文档名称(sessionId),不幸的是,Firestore 安全规则目前不支持此功能 .我建议您在prerequisite 字段中仅将 sessionId 作为字符串存储,或者您也可以为sessionId 添加字符串字段。请记住,exists() 和 get() 函数仅允许您检查文档是否存在,或在给定路径检索文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 2018-03-17
      • 2021-01-10
      • 1970-01-01
      • 1970-01-01
      • 2019-06-17
      相关资源
      最近更新 更多