【发布时间】:2020-08-16 17:28:13
【问题描述】:
背景
我正在尝试在 Firebase Firestore 安全规则中设置继承/引用的访问权限。
在我的示例中,我想控制用户是否可以更新“小时”文档,具体取决于用户是否在“工时文件”。
例如:Hours 文档引用了 ServiceProvider 文档。服务提供商文档有一个子集合“Admins”,其中每个“Admins”记录的文档 ID 是经过身份验证的 UID。
问题
如果我是经过身份验证的用户,则该逻辑适用于 get 方法,但如果我不是,我会得到一个空值异常,因为它找不到文档。我可以先使用 exists 方法检查文档是否存在,但随后我遇到了如何对 exists 方法的结果执行 if 或 ternary 的问题。在其中一个函数中,我得到了 if 和三元的意外值。
数据库结构
注意:这些是每个服务提供商的“管理员”,一个通用的“角色”设置不符合用例。
-ServiceProvider
-Admins (Subcollection)
--Id = Authenticated User Id
--Active = Boolean
-Hours
--mondayStart = String
--mondayEnd = String
--CreatedBy = (reference to ServiceProvider Document)
安全规则
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function getAdminStatus(userId){
//Get the Service Provider who Created the Hours Record
let serviceProviderPath = get(/databases/$(database)/documents/Hours/$(resource.id)).data.CreatedBy;
//Get the Id of the Service Provider based on the Path Reference
let serviceProviderId = get(serviceProviderPath).id;
//Check if Authenticated User Id is in "Admins" subcollection of "ServiceProvider"
let doesAuthenticatedUserExistInAdmins = exists(/databases/$(database)/documents/ServiceProvider/$(serviceProviderId)/Admins/$(userId));
//How do I do this???
//Depending on whether user exists check if Active field is true and return the active results or false for exists
if (doesAuthenticatedUserExistInAdmins == true) {
return get(/databases/$(database)/documents/ServiceProvider/$(serviceProviderId)/Admins/$(userId)).data.Active;
}
else {
return doesAuthenticatedUserExistInAdmins;
}
}
function isUserAdminOfProvider() {
let userId = request.auth.uid;
return getAdminStatus(userId);
}
match /Hours/{Id} {
allow write: if isUserAdminOfProvider();
}
}
}
【问题讨论】:
-
据我了解,如果用户尚未通过身份验证,您的用例将不起作用。也许使用anonymous authentication 可以为您解决这个问题?
-
@tzovourn,没有。我已通过身份验证。经过身份验证的用户确实可以工作,问题是当我使用未经身份验证或非管理员身份验证的用户进行测试时收到的 if 和 null 异常的语法。
-
您能否指出您为实施这些规则而遵循的文档?我在Security Rules中从未见过这样写的函数
-
@tzovourn firebase.google.com/docs/firestore/security/rules-conditions 。 if else 条件是我正在尝试做的理论上的事情。我想检查 null 并根据该表达式返回不同的结果。
标签: firebase google-cloud-firestore firebase-security