Firebase Firestore子集合安全查询 [英] Firebase Firestore subcollection secure query

查看:72
本文介绍了Firebase Firestore子集合安全查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have the following rule in my Cloud Firestore database:

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

这个想法是,您可以在拥有表演的情况下对表演进行读写,或者在登录后创建表演.

The idea is you can read and write to a performance if you own it, or create a performance if you are logged in.

此查询工作正常:

db.collection("performances").whereEqualTo(FieldPath.of("owner"), user.getUid())

但是,如果我想获取场景"子集合的内容,则会出现错误:"com.google.firebase.firestore.FirebaseFirestoreException:PERMISSION_DENIED:缺少权限或权限不足."带有以下查询:

However if I want to get at the contents of the 'scenes' subcollection I get an error: "com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions." That's with the following query:

db.collection("performances")
            .document(performanceID)
            .collection("scenes");

我假设我需要将查询限制为如下所示,但这不能作为whereEqualTo是Query而不是CollectionReference的输出,因此我无法访问"document":

I assume I need to restrict the query to something like the following, but this wont work as the output of whereEqualTo is a Query and not a CollectionReference so I can't access the 'document':

db.collection("performances")
   .whereEqualTo(FieldPath.of("owner"), user.getUid())
   .document(performanceID)
   .collection("scenes");

那么,如果主集合具有安全规则,有谁知道我应该如何访问子集合?

So, does anyone know how I should access a subcollection if the main collection has security rules?

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

我想我可能想出了一个解决方案.我没有意识到我的安全规则默认情况下会拒绝从子集合中读取数据,因此将其更改为允许对表演中的场景进行所有读写都可以使其正常工作:

I think I may have come up with a solution. I didnt realise that my security rule would deny reads from subcollections by default, so changing it to allow all reads and writes to scenes within a performance makes it work fine:

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

推荐答案

首先,请注意规则不会级联,因此您的解决方案实际上会将所有 scenes 子集合中的所有文档打开到世界,而不仅仅是父文档的所有者.

First, please note that rules don't cascade, so your solution actually opens up all the documents in all scenes subcollections to the world, not just the owner of the parent document.

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

You'll need to check the permissions on the parent document using the get() method in Rules.

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

在子收集规则中,我们使用先前捕获的路径段来查找需要检查的父文档.

Here in the subcollection rules we use the previously captured path segments to find the parent document we need to check.

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

Lastly, you'll probably want to tighten up your create rule as well. Currently it allows someone to create a document owned by someone else (or no-one). I doubt you want that. By also checking that the requester's id is in the incoming document you can prevent potential bugs that allow creating documents that the user cannot then read:

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

这篇关于Firebase Firestore子集合安全查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆