Firestore 规则只读取一个集合,其余数据库受限

Firestore rules to read only one collection and rest of the database restricted

所以我有一个项目,其中我已经设置了一些预定义规则,其中包括如果用户经过身份验证则允许读取数据库然后允许一些我不太了解但是当我在我的 firebase 中集成条带然后条带化要求我将这些添加到我的 firestore 规则中。

现在我想让每个人都能阅读一个特定的集合及其一个子集合,但我无法做到这一点

之前我的规则是这样的

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read: if
          request.auth != null;
    }
  }
  match /databases/{database}/documents {
    match /users/{uid} {
      allow read: if request.auth.uid == uid;

      match /checkout_sessions/{id} {
        allow read, write: if request.auth.uid == uid;
      }
      match /subscriptions/{id} {
        allow read: if request.auth.uid == uid;
      }
    }

    match /products/{id} {
      allow read: if true;

      match /prices/{id} {
        allow read: if true;
      }

      match /tax_rates/{id} {
        allow read: if true;
      }
    }
  }
}

之后是这些

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if
          request.auth != null;
    }
     match /organization/{document=**} {
      allow read: if true;     
    }
  }
  match /databases/{database}/documents {
    match /users/{uid} {
      allow read: if request.auth.uid == uid;

      match /checkout_sessions/{id} {
        allow read, write: if request.auth.uid == uid;
      }
      match /subscriptions/{id} {
        allow read: if request.auth.uid == uid;
      }
    }

    match /products/{id} {
      allow read: if true;

      match /prices/{id} {
        allow read: if true;
      }

      match /tax_rates/{id} {
        allow read: if true;
      }
    }
  }
}

但其中 none 允许用户公开阅读组织集合

这是我的数据库,其中包含一些集合,我只希望 organization + 组织的子集合 campaign 公开可用。

您的规则:

rules_version = '2'; 
service cloud.firestore { 
match /databases/{database}/documents { 
match /{document=**} { 
allow read, write: if request.auth != null;
 } 
match /organization/{document=**} { 
allow read: if true; 
} } 
match /databases/{database}/documents { 
match /users/{uid} { 
allow read: if request.auth.uid == uid; 
match /checkout_sessions/{id} {
allow read, write: if request.auth.uid == uid; } 
match /subscriptions/{id} { 
allow read: if request.auth.uid == uid; 
} 
} 
match /products/{id} { 
allow read: if true; 
match /prices/{id} { 
allow read: if true; 
} 
match /tax_rates/{id} { 
allow read: if true; 
} } } }

已修改有效的规则:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
     match /organization/{document=**} {
      allow read: if true;     
    }
   
    match /users/{uid} {
      allow read: if request.auth.uid == "priya";
        }
      match /checkout_sessions/{id} {
        allow read : if request.auth.uid == "priya";
        allow write: if request.auth.uid == "priya";
      }
      match /subscriptions/{id} {
        allow read : if true;
      }
      match /products/{id} {
      allow read: if true;
    }
      match /prices/{id} {
        allow read: if true;
      }
      match /tax_rates/{id} {
        allow read: if true;
      }
    }
  }

解释:

  1. 我删除了:

    match /{document=**} { 
    allow read, write: if request.auth != null; } 
    

    match /{document=**} 匹配整个数据库中的所有文档。 那里的通配符实际上“吞噬”了整个路径 文档,以便进一步匹配。您还在其下方嵌套了 match /organization/{document=**},但实际上并没有 有任何意义(因为你不能在一个下嵌套更多文档 最外层文件)。我的规则有效,因为我匹配 顶层的组织集合,不嵌套在任何东西下 否则。

    来源 :

    https://firebase.google.com/docs/rules/basics#default_rules_locked_mode

  2. 我改了:

        match /organization/{document=**} { 
            allow read: if true;
    
    
    
    To 
    
        match /organization/{org}/campaign/{document=**} {
              allow read: if true;     
            }
    
    As you specified, you only want organization + organization's
    subcollection campaign to be publicly available.  I have designed a
    Firestore security rule that allows only documents and
    subcollections inside your campaign sub collection to have public
    read access. If you try to give documents under organization
    collection public read access, it will be denied. As the public read
    access only applies to documents/subcollections under campaign sub
    collection which is under organization collection, If you want any
    collections/documents inside organization to have public read
    access, you can change this to 
    
    match /organization/{document=**}{ 
        allow read: if true;  }
    

    来源:

    https://firebase.google.com/docs/firestore/security/rules-structure#recursive_wildcards

  3. match /databases/{database}/documents {

    This was a duplicate/ repeat of the first
    /databases/{database}/documents and it pretty much means matching to
    the default database we have and it's where all our Firestore rules
    should be inside.  Creating another /databases/{database}/documents
    is not correct and does not make sense.
    

    来源:

    https://firebase.google.com/docs/firestore/security/rules-structure#overlapping_match_statements

您应该使用 Firestore 模拟器 测试您的规则。上述规则已按照此documentation and this video

进行了检查和修改

如何测试规则?

打开您的 Firebase 控制台。转到 Firestore 数据库,单击此屏幕截图中突出显示的规则选项卡。单击 Rule Playground,您可以在此处模拟和测试您的规则。

如果您正在检查 public 读取访问权限,请将模拟类型更改为 'get',指定确切的您要在 Location 字段中检查规则的位置路径,例如。 subscriptions/{id} 用于匹配 /subscription/{id} 规则。将 身份验证设置为关闭 。 运行 模拟器,点击 运行 按钮,您将收到一条 green/red 消息,说明您的规则已分别测试 successfully/denied。

如果您正在检查经过身份验证的读取访问,请将模拟类型更改为'get',指定确切的位置路径你想检查位置字段中的规则。例如。 users/{uid} 匹配 /users/{uid} 规则。将 身份验证设置为开启 。使用一些随机值指定 Firebase uid、电子邮件、名称、phone 数字。 运行 模拟器,点击 运行 按钮,您将收到一条 green/red 消息,分别说明您的规则已经过测试 successfully/denied。在这里你必须记住 request.auth.uid 应该等于 uid。当我们在模拟器上测试它时,我们硬编码 uid 中的值,因为当我们为 Firebase uid 赋值时 request.auth.uid 已经设置。在生产环境中,您可以在应用程序中设置 uid。

如果您正在检查经过身份验证的写入访问,请将模拟类型更改为'create',指定确切的位置路径你想检查位置字段中的规则。例如。 checkout_sessions/{id} 用于匹配 /checkout_sessions/{id} 规则。将 身份验证设置为开启 。使用一些随机值指定 Firebase uid、电子邮件、名称、phone 数字。 运行 模拟器,点击 运行 按钮,您将收到一条 green/red 消息,分别说明您的规则已经过测试 successfully/denied。在这里你必须记住 request.auth.uid 应该等于 uid。当我们在模拟器上测试它时,我们硬编码 uid 中的值,因为当我们为 Firebase uid 赋值时 request.auth.uid 已经设置。在生产环境中,您可以在应用程序中设置 uid。