应用中的Firestore查询可拒绝权限,而模拟器可以正常运行

时间:2018-06-29 17:56:03

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

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

FirebaseFirestore.getInstance().collection("events").document( eventId ).collection("instances").get().addOnCompleteListener( .... )

这给出了拒绝堆栈跟踪的权限: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 );
      }
    } 

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

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

2 个答案:

答案 0 :(得分:4)

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

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;
    }
  }
}

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

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

//此查询将失败

db.collection("stories").get()

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

答案 1 :(得分:0)

如果使用批处理修改,则PERMISSION_DENIED错误消息似乎已出错,并且指示的元素没有足够的权限可能是错误的:指示的元素具有足够的权限,但是批处理修改中的另一个元素没有足够的权限。