Firestore有一个DocumentReference类型,它是另一个firestore文档的"指针".使用firebase JavaScript客户端,您可以直接在引用上访问属性(例如文档"id").
例如,如果有一个文档的docRef属性是firestore DocumentReference:
const retrievedDoc = await getFirestoreDocument();
console.log(retrievedDoc.docRef.id); // "jRmSeMYDMKiOPGsmkdaZ"
Run Code Online (Sandbox Code Playgroud)
我试图在firestore规则中完成同样的事情.有一个名为的自定义函数isOwner.它使用get文档路径上的firestore规则调用,然后尝试访问docRef.id它,就好像它是上面的JavaScript客户端一样.
get(/databases/$(database)/documents/path/to/$(id)).data.docRef.id
Run Code Online (Sandbox Code Playgroud)
将文档id的值与当前用户的值进行比较.但是当我使用模拟器和实际代码测试时,它会失败.我觉得这应该有效,但事实并非如此.
什么做的工作是存储和直接使用id的值作为字符串(例如get(/path/id).docId),而不是DocumentReference的.
我是否应该能够id在firestore规则中访问DocumentReference 的值?难道我做错了什么?
我想避免get在规则中执行第二个文档,如本SO答案所述.对于此规则的每个触发器,这是第二次"读取".而且我认为get无论如何都不会在电话上提供文件ID(这就是我需要的).
我有点卡在这里,因为没有办法调试这些规则.我很感激以下规则的帮助.
我想访问:
/modules/module-id/sessions/session-id/parts/
与null第一部分的比较hasCompletedPrerequisiteSession()效果很好,第二部分没有!
该路径/modules/moduleId/sessions/sessionId/prerequisite指向参考字段.
service cloud.firestore {
match /databases/{database}/documents {
function hasCompletedPrerequisiteSession(moduleId,sessionId) {
// this part works well
return getPrerequisiteSession(moduleId,sessionId) == null ||
// !!! this part does not work !!!
hasCompleted(getPrerequisiteSession(moduleId,sessionId).id);
}
function getPrerequisiteSession(moduleId,sessionId) {
return get(/databases/$(database)/documents/modules/$(moduleId)/sessions/$(sessionId)).data.prerequisite;
}
function hasCompleted(sessionId) {
return exists(/databases/$(database)/documents/progress/$(request.auth.uid)/sessions/$(sessionId));
}
match /modules/{moduleId}/sessions/{sessionId}/parts/{partId} {
allow read: if hasCompletedPrerequisiteSession(moduleId,sessionId);
}
}
}
Run Code Online (Sandbox Code Playgroud)
(如果我将会话ID存储为字符串而不是对会话的引用,它可以正常工作.)
编辑
问题
modules/moduleId/owner指向该类型的字段reference.获取引用文档的id的正确方法是什么?get(../modules/moduleId).data.owner.data.id或者get(../modules/moduleId).data.owner还是其他什么东西?