![](/img/trans.png)
[英]Firestore security rules how to check if document was created by user (is owner)
[英]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.