繁体   English   中英

Firestore 安全规则文档 ID 导致 Null 值错误

[英]Firestore security rules document id causing Null value error

我正在努力保护我的 Firestore 数据库,但在使用集合通配符时遇到了问题。 我有一个名为study的根级集合,我只想在status字段设置为“已发布”时才允许读取。

我目前的安全规则如下

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
   
  ...

  function isStudyPublished(studyId) {
    return get(/databases/$(database)/documents/study/$(studyId)).data.status == "published";
  }

  ...

  // Match for participant permissioning
  match /study/{studyId}/{document=**} {
    // Deny all requests to create, update, or delete the study
    allow create, update, delete: if false

    // Allow the requestor to read the study if it is published
    allow read: if isStudyPublished(studyId)
  }

  ...

  }
}

此安全规则在请求单个文档时非常有效,但在执行集合级别查询时则无效。 我收到错误消息: Null value error. for 'list' Null value error. for 'list' 我知道 Firestore 规则不能充当过滤器,但是,我相信我的查询应该只请求status字段等于“已发布”的文档。

这是我的两个查询:

// successfully retrieves a single document
export const getStudy: GetStudy = (studyId) => {
  return new Promise((resolve, reject) => {
    getDoc(doc(firestore, COLLECTION_KEYS.STUDY, studyId))
      .then((doc) => {
        resolve(dataToStudy(doc.id, doc.data()));
      })
      .catch((error) => reject(error));
  });
};
// fails to retrieve multiple documents
export const getStudies: GetStudies = (cursor) => {
  const studies: StudyDoc[] = [];
  return new Promise((resolve, reject) => {
    let q = query(collection(firestore, COLLECTION_KEYS.STUDY), where("status", "==", "published"), orderBy(FIELD_KEYS.UPDATED));

    if (cursor) q = query(q, startAfter(cursor));

    getDocs(q)
      .then((snapshot) => {
        snapshot.forEach((doc) => {
          studies.push(dataToStudy(doc.id, doc.data()));
        });

        return resolve([studies, snapshot.docs[snapshot.docs.length - 1]]);
      })
      .catch((error) => {
        return reject(error);
      });
  });
};

我最初的想法是我的集合查询正在请求不符合安全规则的文档,但在盯着查询之后,我认为这不是真的......

作为测试,我更改了我的安全规则以测试使用调试功能的帮助会通过什么。 我最终意识到每次引用studyId变量时检查都会失败。 例如,以下 match 语句失败。

match /study/{studyId}/{document=**} {
  // Deny all requests to create, update, or delete the study
  allow create, update, delete: if false

  // Allow the requestor to read the study if it is published
  allow read: if debug(debug(true) && (debug(studyId) != null));
}

查看firestore-debug.log时,如果我运行请求单个文档的查询,我会看到以下记录:

bool_value: true

string_value: "rMxuVTJ0O15qPjMbpEU1"

bool_value: true

但是,在运行收集查询时会记录以下内容:

bool_value: true

我从来没有遇到过文档 id 通配符抛出这样的错误。 我无法确定这是否是我的匹配语句或查询的错误,但感谢您提供任何帮助。

我不确定您的用例到底是什么,但是在尝试从正在访问或读取的文档中读取数据时,您不必使用get() 您应该改用resource.data 请参阅下面的 Firestore 规则:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    function isStudyPublished() {
      return resource.data.status == "published";
    }

    // Match for participant permissioning
    match /study/{studyId}/{document=**} {

      // Deny all requests to create, update, or delete the study
      allow create, update, delete: if false

      // Allow the requestor to read the study if it is published
      allow read: if isStudyPublished();
    }
  }
}

更新:

当访问您的子集合时,您的查询应该与您的安全规则相匹配。 您应该拥有根集合的文档 ID 才能访问您的子集合。 例如:

// Document-ID refers to study's document
let q = query(collection(db, "study", <DOCUMENT-ID>, <SUBCOLLECTION-NAME>), where(<FIELDNAME>, "==", <STRING>));

安全规则:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /study/{studyId} {
      // Deny all requests to create, update, or delete the study
      allow create, update, delete: if false

      // Do all restrictions here for the study collection.

      function isStudyPublished() {
        return get(/databases/$(database)/documents/study/$(studyId)).data.status == "published";
      }

      // Rules for accessing subcollection of study collection.
      match /subcollection-name/{docId} {
        // Allow read if the document referenced from the study collection is published.
        allow read: if isStudyPublished();

        // Do all restrictions here for study's subcollection.
      }
    }
  }
}

如果study集合中的引用文档标记为已发布,则上述示例规则将仅允许读取子集合文档。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM