Firebase 安全规则错误“对象上未定义属性资源”

Lak*_*ker 5 firebase-security

我有一个函数(并且我已经在没有函数的情况下对其进行了测试,只是为了检查参考或其他内容是否没有问题):

function resourceIsValidSomething() {
  return request.resource.data.something is string ...;
}
Run Code Online (Sandbox Code Playgroud)

进而:

allow create: if request.auth != null && resourceIsValidSomething();
Run Code Online (Sandbox Code Playgroud)

allow update: if request.auth != null && resourceIsValidSomething();
Run Code Online (Sandbox Code Playgroud)

但在测试更新规则时我收到此错误消息:

错误:simulator.rules 行 [19],列 [17]。对象上未定义属性资源。

根据文档,我的规则应该是正确的。

我究竟做错了什么?

真实例子:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    function isGod() {
        return get(/databases/$(database)/documents/employees/$(request.auth.uid)).data.role == 'god';
    }

    function allowedUser() {
        return request.resource.data.assignedTo.uid == request.auth.uid || isGod();
    }

    match /stores/{storeId} {
        allow read: if request.auth != null;

        match /imeis/{imeiId} {

        function resourceIsValidImei() {
            return request.resource.data.imei is string && 
            request.resource.data.imei.size() > 0 &&
            request.resource.data.type is string &&
            request.resource.data.type.size() > 0 &&
            request.resource.data.dateAdded is timestamp &&
            request.resource.data.createdBy.uid == request.auth.uid;
        }

        allow read: if request.auth != null;

        allow create: if request.auth != null &&
            isGod() && resourceIsValidImei();

        allow update: if request.auth != null && allowedUser();
      }
Run Code Online (Sandbox Code Playgroud)

Rea*_*lar 8

\n

\xe2\x80\x9c 对象\xe2\x80\x9d 上未定义属性资源

\n
\n

您不能在 Firebase 规则表达式中使用不存在的属性。

\n

例如,以下内容将引发类似的错误。

\n
read: if request.foobar == \'some value\';\n
Run Code Online (Sandbox Code Playgroud)\n

那是因为foobar不存在,而规则会提出它是undefined\'some value\'与右侧的比较永远不会发生,并且不会评估其余规则表达式。

\n

对象就像request实现Map()接口一样。

\n

https://firebase.google.com/docs/reference/rules/rules.Map

\n

Map.get()因此,您可以使用不会引发错误并为缺失条目提供默认值的方法重写规则。

\n
read: if request.get(\'foobar\', null) == \'some value\';\n
Run Code Online (Sandbox Code Playgroud)\n

所以现在我们可以安全地引用foobar在我们的规则中引用。

\n
\n

我有一个函数(并且我已经在没有函数的情况下对其进行了测试,只是为了检查参考或其他内容是否存在问题):

\n
\n

并非规则中的所有请求都会产生resource. 如果文档不存在,则永远不会设置resourceon 属性。request因此尝试读取它会产生上述错误。您可以通过检查 来解决此问题null

\n
function resourceIsValidSomething() {\n  return request.get(\'resource\', null) != null && request.resource.data.something;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

您可能仍然会收到类似的规则错误false for "get" & L10

\n

那是因为request.get(\'resource\', null) != null检查将不符合规则。您可以决定允许访问不存在的文档,以便完成查询。

\n

该规则看起来像这样。

\n
function resourceIsValidSomething() {\n  return request.get(\'resource\', null) == null || request.resource.data.something;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

因此,允许访问缺失的资源或仅使用data.something.

\n

由您决定哪种方法最适合您的用例。

\n