首页 > 解决方案 > 具有函数的 Firestore 安全规则返回未知错误

问题描述

我有一组用户:

users:
   userUid:
       group: "group_1"
       name: "Paul"
   userUid:
       group: "group_1"
       name: "Gregor"
   userUid:
       group: "group_2"
       name: "Mary"

和 ShoppingLists 的集合:

shoppingList:
   listUid:
        isActive: true,
        group: "group_1",
        name: "list_ONE"
   listUid:
        isActive: false,
        group: "group_1",
        name: "list_TWO"
   listUid:
        isActive: true,
        group: "group_2",
        name: "list_THREE"

我想限制读取/更新访问权限,以便只有属于特定组的人才能编辑/读取同一组内的文档。

我尝试使用以下规则查看文档,但在 Firabase 控制台模拟器中我收到“未知错误”并且我没有得到任何控制台提示:

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

    function signedIn() {
      return request.auth.uid != null;
    }

    function getGroup(usr) {
      return usr.data.group;
    }

    function isInGroup(usr, groupName) {
       return signedIn() && (getGroup(usr) == groupName);
    }


    match /users/{user} {
      // Read access needed to get the user group
        allow read: if signedIn();  
    }


    match /shoppingLists/{shoppingList} {
      // Everybody can create a new list
      allow create: if signedIn();

      // Only people from the list group can read/update that list
      allow read: if isInGroup(get(/databases/$(database)/documents/users/$(request.auth.uid)), resource.data.group);

      allow update: if isInGroup(get(/databases/$(database)/documents/users/$(request.auth.uid)), request.resource.data.group)
                       && request.resource.data.isActive;
    }
  }
}

标签: firebasegoogle-cloud-firestorefirebase-security

解决方案


您没有在规则中正确使用 get() 。您将字符串路径传递给涉及集合和文档的文档,但 get() 要求您传递 1) 不是字符串且 2) 以 with 为前缀的路径对象/databases/$(database)/documents。您应该阅读有关访问其他文档的文档以查看一些示例,例如:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      // Make sure a 'users' document exists for the requesting user before
      // allowing any writes to the 'cities' collection
      allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid))

      // Allow the user to delete cities if their user document has the
      // 'admin' field set to 'true'
      allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true
    }
  }
}

推荐阅读