簡體   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