Firebase实时数据库规则检查数组是否包含

7

我的身份验证令牌包括一个 stores 属性。该属性是一个数组,包含用户被允许访问的所有商店的ID。例如:stores: ['abc123', 'def456']

现在,在我的 Firebase 实时数据库中,我正在以这种方式保存特定于商店的数据:

{
  "stores": {
    "abc123": {
      "data": "mydata"
    },
    "def456": {
      "data": "mydata"
    }
  }
}

如果用户的stores属性数组包含他们想要访问的storeID特定数据,他们就可以访问实时数据库数据。

我希望我的规则看起来像:

{
  "rules": {
    "stores": {
      "$store_id": {
        ".read": "auth.token.stores.includes($store_id)"
      }
    }
  }
}

这是不可能的。我收到了以下错误信息:

保存规则出错 - 第5行: 类型错误: 目标上的函数调用不是函数。

在firebase规则中,搜索令牌属性数组是否可行,还是必须使用对象?感谢任何答案!


1
请编辑您的问题并将您的数据库结构添加为JSON文件。您可以通过在Firebase控制台中的溢出菜单(⠇)中单击“导出JSON”来轻松获取它。 - Alex Mamo
2个回答

6

Firebase实时数据库没有includes()方法来检查一个值是否在数组中存在。你可以将声明(claims)存储为Map,而不是数组,如下所示:

// custom claims
{
  stores: {
    store1: true,
    store2: true,
    store3: false
  }
}

然后您可以使用以下规则检查用户是否对特定商店具有访问权限:

{
  "rules": {
    "stores": {
      "$store_id": {
        ".read": "auth.token.stores[$store_id] == true"
      }
    }
  }
}

1
我已经认为这是不可能的了...无法通过数组在RT规则中进行检查是Firebase网站上的一个大缺陷。 - Maximilian Dietel
同意 - 如果我想要一个双向关联,那么这就变得特别烦人。如果$uid1可以访问$uid2的值,并且它们在关联列表中,那么$uid2也可以访问$uid1的值,那么列表中必须同时存在uid1:uid2和uid2:uid1。 - Jimbo

-1

您可以使用 List 中的 in 运算符

v in x
检查值 v 是否存在于列表 x 中。

'a' in ['a','b'] == true

示例安全规则如何实现

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      
      match /stores/{storeId} {
        allow read: if isAuthenticated() && isUserAllowed();
      }
      
      function isAuthenticated() {
        return request.auth != null;
      }

      function isUserAllowed() {
        return request.auth.uid in resource.data.stores
      }

    }
  }
}

1
OP正在使用实时数据库,但是你的答案中包含云端 Firestore 数据库的安全规则。 - Dharmaraj
哦,我错过了@Dharmaraj - Min ho Kim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接