【问题标题】:I can't check if field exists in document when working on firestore rules在处理 Firestore 规则时,我无法检查文档中是否存在字段
【发布时间】:2020-06-29 13:06:25
【问题描述】:

我正在开发一个包含测验文档的应用程序 Firestore 数据库。每个文档都可能有一个名为 peopleCanAccess 的字符串数组字段。

我想在规则中做什么? 如果文档具有此字段 (peopleCanAccess),则 peopleCanAccess 中唯一存在的人可以阅读该文档。如果此字段不存在,则所有经过身份验证的人都可以访问它。

我试过了:

 function existingData() {
      return resource.data;
    }

 function isAuthenticated() {
      return request.auth != null;
    }

    function getUid() {
      return request.auth.uid;
    }

    function fieldExists(data, field) {
      return !isUndefined(data, field) && !isNull(data, field);
    }

    function isUndefined(data, field) {
      return !data.keys().hasAll([field]);
    }

    function isNull(data, field) {
      return data[field] == null;
    }



 match /quiz/{quizID}{
        allow read : if 
        (isAuthenticated() && existingData().owner == getUid())
        || (isAuthenticated() && !('peopleCanAccess' in existingData().keys()))
        || (isAuthenticated() && getUid() in existingData().peopleCanAccess)
           // !fieldExists(resource.data, 'peopleCanAccess');

        ...

}

这些规则无法正常工作。

示例: id 为 tcsFStMdplOJSyZsluJBLHeOuJs1 的用户可以访问上图中提到的测验,尽管他未列在 peopleCanAccess 字段中

查询:

 db.collection("quiz")
                .whereEqualTo("id", quizId)
                .get()
                .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                    @Override
                    public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                        if (queryDocumentSnapshots.isEmpty()){

                        }else {
                            QuizItem quizItem = queryDocumentSnapshots.getDocuments().get(0).toObject(QuizItem.class);
                            accessedQuiz.postValue(quizItem);
                        }
                    }
                });

【问题讨论】:

  • “这些规则无法正常工作。”请编辑您的问题以包含规则无法正常工作的示例。
  • 您的问题应该包括您正在使用的实际数据以及尝试使用该数据的客户端应用程序代码。如果没有所有这些信息,很难判断可能出了什么问题。

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


【解决方案1】:

终于找到了解决办法,

我在 Rules Playground 中检查了规则,并没有发现我的规则有任何问题。它工作正常问题出在我的客户端查询中。 我在文档中找到了这个:

在编写查询以检索文档时,请记住安全性 规则不是过滤器——查询是全有或全无。为了节省您的时间和 资源,Cloud Firestore 根据其潜力评估查询 结果集而不是您所有的实际字段值 文件。如果查询可能会返回文档 客户端没有读取权限,整个请求失败。

注意:您可以将读取规则分解为获取和列出规则。获取规则 适用于单一文件的请求,列表规则适用于 查询和收集请求。

here

我是如何解决我的问题的:
1-打破读写规则:

 match /quiz/{quizID}{
              allow get : if 
              (isAuthenticated() && getUid() in existingData().peopleCanAccess)
              ||
              (isAuthenticated() && !checkIfExistsInKeys(existingData(), 'peopleCanAccess'))

              allow list : if 
              (isAuthenticated() && getUid() == existingData().owner)

              allow create : if (isAuthenticated() && getUid() == existingData().owner);
              allow update : if (isAuthenticated() && getUid() == existingData().owner);
              allow delete : if (isAuthenticated() && getUid() == existingData().owner);
       }

2- 更改我的客户端查询以检索一个文档:

db.collection("quiz")
                .document(quizId)
                .get()
                .addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                    @Override
                    public void onSuccess(DocumentSnapshot documentSnapshot) {
                        if (!documentSnapshot.exists()){

                        }else {
                            QuizItem quizItem = documentSnapshot.toObject(QuizItem.class);
                            accessedQuiz.postValue(quizItem);
                        }
                    }
                });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 2020-09-09
    • 2020-03-09
    • 1970-01-01
    • 2019-03-04
    • 2021-05-23
    • 2018-09-29
    • 1970-01-01
    相关资源
    最近更新 更多