哪种Firebase规则将防止基于其他字段的集合中出现重复项?

问题描述 投票:8回答:1

我正在创建一个应用程序,允许用户创建项目,然后允许其他用户订阅这些项目。我正在努力制定规则,以防止用户多次订阅某项商品。

这是我的数据结构的一个示例(匿名,因此为“ OMITTED”值):

{
    "OMITTED" : {
        "name" : "Second",
        "body" : "this is another",
        "userName" : "Some User",
        "userId" : "OMITTED",
        "created" : 1385602708464,
        "subscribers" : {
            "OMITTED" : {
                "userName" : "Some User",
                "userId" : "OMITTED"
            }
        }
    }
}

目前是我的Firebase规则:

{
  "rules": {
    ".read": true,
    ".write": "auth != null",
    "items": {
      "$item": {
        ".write": "!data.exists()",
        ".validate": "newData.hasChildren(['name', 'body', 'userId', 'userName']) && newData.child('userId').val() == auth.id",
        "subscribers": {
          "$sub": {
            ".validate": "newData.hasChildren(['userId', 'userName']) && newData.child('userId').val() != data.child('userId').val()"
          }
        }
      }
    }
  }
}

如何防止用户多次订阅?我需要根据什么规则来防止基于subscribersuserId列表中的重复用户?

validation firebase firebase-security
1个回答
6
投票

由于安全规则无法迭代记录列表来查找包含特定数据位的记录,因此,这里的窍门是通过ID来存储记录,以便于访问。 denormalization上有一篇很棒的文章,提供了对该实践的一些很好的见解。

在这种情况下,如果您的用例允许,您可能只想切换数据结构,以便通过用户的ID存储记录,而不是像这样将ID作为值存储在记录中:

/users/user_id/items/item_id/subscribers/user_id/

实际上,正如您将在非规范化中看到的那样,您甚至可以进一步拆分内容,这取决于数据的确切大小以及以后的读取方式:

/users/user_id
/items/user_id/item_id
/subscribers/item_id/user_id

使用这两种格式中的任何一种,您现在都可以使用以下类似的方法很好地防止重复并锁定安全性:

{
   "users": {
      "$user_id": { ".write": "auth.id === $user_id" }
   },
   "subscribers": {
      "$subscriber_id": { ".write": "auth.id === $subscriber_id" }
   }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.