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

时间:2019-12-11 19:28:52

标签: firebase-security

我有一个功能(并且我已经在没有功能的情况下对其进行了测试,只是为了检查引用或某些内容是否存在问题):

function resourceIsValidSomething() {
  return request.resource.data.something is string ...;
}

然后:

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

allow update: if request.auth != null && resourceIsValidSomething();

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

  

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

根据documentation,我的规则应该正确。

我在做什么错了?

真实示例:

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();
      }

2 个答案:

答案 0 :(得分:2)

<块引用>

“未在对象上定义属性资源”

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

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

read: if request.foobar == 'some value';

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

request 这样的对象实现了 Map() 接口。

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

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

read: if request.get('foobar', null) == 'some value';

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

<块引用>

我有一个函数(我在没有函数的情况下测试了它,只是为了检查参考或其他东西是否有问题):

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

function resourceIsValidSomething() {
  return request.get('resource', null) != null && request.resource.data.something;
}

您可能仍会收到类似 false for "get" & L10

的规则错误

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

规则看起来像这样。

function resourceIsValidSomething() {
  return request.get('resource', null) == null || request.resource.data.something;
}

因此允许访问缺少的资源或仅访问带有 data.something 的资源。

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

答案 1 :(得分:-1)

尝试从request.的任何实例中删除request.resource。即更改:

return request.resource.data.assignedTo.uid == request.auth.uid || isGod();

return resource.data.assignedTo.uid == request.auth.uid || isGod();

Google似乎在某些领域更新了文档,但在其他方面没有更新,但是resource不再存储为request的属性