firebase firestore 规则验证了对所有集合的访问,但一个集合除外

GMa*_*Man 5 firebase firebase-security google-cloud-firestore

我有以下firestore结构,基本上是3个集合

publicdata protecteddata1 protecteddata2

我希望将 protecteddata1 和 protecteddata 2 以及整个 Firestore 数据库作为经过身份验证的用户使用。但我希望公众拥有对“publicdata”集合的只读访问权限..

以下是我的尝试,但不起作用

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read;
      allow write: if (request.auth.uid != null);
    }
    match /publicdata {
       allow read;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Ary*_*tey 11

您可以使用我创建的以下函数来执行此操作

function isUserAuthenticated() {
    return request.auth.uid != null; 
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if isUserAuthenticated();
    }
    
    match /publicdata/{itemId} {
      allow read : if true;
      allow create : if isUserAuthenticated();
      allow update: if isUserAuthenticated();
      allow delete: if isUserAuthenticated();
    }

    /* Functions */
    function isUserAuthenticated() {
      return request.auth.uid != null; 
    }
  }
}   
Run Code Online (Sandbox Code Playgroud)


Fra*_*len 8

正如其他人所解释的那样,如果同一个文档有多个匹配项,它们将被或运算在一起,因此您不能用它来实现异常。

不过,您可以做的是捕获变量中的集合名称,然后在单个匹配中实现异常:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{collection}/{document=**} {
      allow read: if collection != 'publicdata';
      allow write: if (request.auth.uid != null);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,这里我们允许读取除 之外的所有集合publicdata


Dou*_*son 7

这里的递归通配符允许访问所有集合:

    match /{document=**} {
      allow read;
      allow write: if (request.auth.uid != null);
    }
Run Code Online (Sandbox Code Playgroud)

一旦任何规则允许访问一个集合,该访问就不能被任何其他规则撤销。

您需要做的是按照自己的规则调用每个单独的集合。是的,这有点痛苦,但这是您唯一的选择。它还使读者非常清楚您的规则,您打算允许每个集合的内容。

同样值得注意的是,这条规则实际上根本没有做任何事情,因为它不匹配任何文档:

    match /publicdata {
       allow read;
    }
Run Code Online (Sandbox Code Playgroud)

如果要匹配 publicdata 集合中的文档,则需要一个与该集合中的文档匹配的通配符:

    match /publicdata/{id} {
       allow read;
    }
Run Code Online (Sandbox Code Playgroud)

请记住,规则匹配用于访问的文档,而不是集合。