Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/221.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Firebase Firestore子集合安全查询_Android_Firebase_Google Cloud Firestore - Fatal编程技术网

Android Firebase Firestore子集合安全查询

Android Firebase Firestore子集合安全查询,android,firebase,google-cloud-firestore,Android,Firebase,Google Cloud Firestore,我的云Firestore数据库中有以下规则: service cloud.firestore { match /databases/{database}/documents { match /performances/{performanceId} { allow read, update, delete: if request.auth.uid == resource.data.owner; allow create: if request.auth.uid

我的云Firestore数据库中有以下规则:

service cloud.firestore {
  match /databases/{database}/documents {
    match /performances/{performanceId} {
      allow read, update, delete: if request.auth.uid == resource.data.owner;
      allow create: if request.auth.uid != null;
    }
  }
}
其思想是,如果您拥有某个性能,您可以对其进行读写操作;如果您登录,则可以创建一个性能

此查询工作正常:

db.collection("performances").whereEqualTo(FieldPath.of("owner"), user.getUid())
但是,如果我想获取“场景”子集合的内容,我会得到一个错误:“com.google.firebase.firestore.firebase firestoreexception:权限\被拒绝:权限缺失或不足。” 这与以下查询有关:

db.collection("performances")
            .document(performanceID)
            .collection("scenes");
我假设我需要将查询限制为以下内容,但这无法作为其中equalto是查询而不是CollectionReference的输出,因此我无法访问“文档”:

db.collection("performances")
   .whereEqualTo(FieldPath.of("owner"), user.getUid())
   .document(performanceID)
   .collection("scenes");
那么,如果主集合有安全规则,有人知道我应该如何访问子集合吗

更新1(因为代码未在下面的注释中格式化)


我想我可能已经想出了一个解决办法。我没有意识到,默认情况下,我的安全规则将拒绝从子集合读取,因此将其更改为允许在一次演出中对场景进行所有读取和写入,这样就可以正常工作:

service cloud.firestore {
  match /databases/{database}/documents {
    match /performances/{performanceId} {
      allow read, update, delete: if request.auth.uid == resource.data.owner;
      allow create: if request.auth.uid != null;
      
      match /scenes/{sceneId} {
        allow read, write: if true
      }
    }
  }
}

首先,请注意规则不会层叠,因此您的解决方案实际上会向世界打开所有
场景
子集合中的所有文档,而不仅仅是父文档的所有者

您需要使用规则中的
get()
方法检查父文档的权限

service cloud.firestore {
   match /databases/{database}/documents {
      match /performances/{performanceId} {
         allow read, update, delete: if request.auth.uid == resource.data.owner;
         allow create: if request.auth.uid != null;

         function parentDoc() {
             return get(/databases/$(database)/documents/performances/$(performanceId)).data;
         }

         match /scenes/{sceneId} {
            allow read, write: if parentDoc().owner = request.auth.uid;
         }
      }
   }
}
在子集合规则中,我们使用先前捕获的路径段来查找需要检查的父文档

最后,您可能还需要收紧
create
规则。目前,它允许某人创建其他人(或无人)拥有的文档。我怀疑你想要那个。通过检查传入文档中是否有请求者的id,您可以防止潜在的错误,这些错误允许创建用户无法读取的文档:

allow create: if request.auth.uid != null && request.auth.uid == request.resource.data.owner;

我想我可能已经想出了一个解决办法。我没有意识到,默认情况下,我的安全规则会拒绝从子集合读取,因此将其更改为允许对性能中的场景进行所有读取和写入,这样可以正常工作:service cloud.firestore{match/databases/{database}/documents{match/performances/{performanceId}{allow read,update,delete:if request.auth.uid==resource.data.owner;allow create:if request.auth.uid!=null;match/scenes/{sceneId}{allow read,write:if true}}}}还检查通配符语法,
{name=**}
。这真的很有帮助。谢谢,我没有意识到父文档中的规则也不会影响嵌套集合。
parentDoc()
函数在检查所有权方面对我很有帮助。谢谢!