【问题标题】:Inherited Access Firebase Security Rules继承访问 Firebase 安全规则
【发布时间】: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


【解决方案1】:

要检查记录是否存在 AND (&&) 如果存在,值是否为真,您可以使用以下命令:

let doesExist = exists(/databases/$(database)/documents/ServiceProvider/$(serviceProviderId)/Admins/$(userId));
let isActive =  get(/databases/$(database)/documents/ServiceProvider/$(serviceProviderId)/Admins/$(userId)).data.Active;
return doesExist && isActive; 

如果您尝试只使用 isActive 并返回它,您可能会返回导致异常的 null,但是,如果您使用 && 运算符,则 null 将返回 false 并允许您继续进行而不会出现异常。 null 在表达式中被认为是 false,但直接返回的只是 null

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 2022-01-19
    • 2019-08-14
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多