应用程序中的 Firestore 查询授予权限被拒绝,而模拟器工作正常

Pet*_*ter 4 firebase firebase-security google-cloud-firestore

在我基于 Firestore 的应用程序中,我使用以下查询来检索一些数据:

FirebaseFirestore.getInstance().collection("events").document( eventId ).collection("instances").get().addOnCompleteListener( .... )
Run Code Online (Sandbox Code Playgroud)

这给出了一个权限被拒绝的堆栈跟踪:FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.

我的规则的相关部分如下:

match /events/{eventId} {

      allow create: if isCurrentUser( request.resource.data.owner );
      allow read: if isOwner(eventId) || isAnAdmin( eventId );
      allow update: if isOwner( eventId ) || isAtLeastEventAdmin( eventId );
      allow delete: if isOwner( eventId ); 

      match /instances/{instanceId} {
        allow read: if isOwner(eventId) || isAnAdmin( eventId );
        allow write: if isOwner( eventId ) || isAtLeastInstanceAdmin( eventId );
      }
    } 
Run Code Online (Sandbox Code Playgroud)

在控制台模拟器中,对某个实例的查询工作正常,但是一旦我对“实例”集合启动查询,我就会遇到这个问题(这是我无法在模拟器中模拟的)。请注意,isOwner( eventId )在这种情况下返回 true。

如何为实例启用查询?在我看来,“读取”权限应该足以允许查询吗?

aja*_*xon 6

如果查询可能包含任何权限失败的文档,则查询将失败。

https://firebase.google.com/docs/firestore/security/rules-query

以下安全规则使用 request.auth 和 resource.data 变量将每个故事的读写访问权限限制为其作者:

service cloud.firestore {
  match /databases/{database}/documents {
    match /stories/{storyid} {
      // Only the authenticated user who authored the document can read or write
      allow read, write: if request.auth.uid == resource.data.author;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

假设您的应用程序包含一个页面,该页面向用户显示他们创作的故事文档列表。您可能希望可以使用以下查询来填充此页面。但是,此查询将失败,因为它不包含与您的安全规则相同的约束:

无效:查询约束与安全规则约束不匹配

// 此查询将失败

db.collection("stories").get()
Run Code Online (Sandbox Code Playgroud)

即使当前用户实际上是每个故事文档的作者,查询也会失败。这种行为的原因是,当 Cloud Firestore 应用您的安全规则时,它会根据其潜在结果集而不是数据库中文档的实际属性来评估查询。如果查询可能包含违反安全规则的文档,则查询将失败。