Validation 什么Firebase规则可以防止基于其他字段的集合中出现重复?

Validation 什么Firebase规则可以防止基于其他字段的集合中出现重复?,validation,firebase,firebase-security,Validation,Firebase,Firebase Security,我正在创建一个应用程序,它允许用户创建项目,然后允许其他用户订阅这些项目。我正在努力制定一个规则,防止用户订阅一个项目不止一次 以下是我的数据结构示例(匿名,因此为“省略”值): 以下是我目前的Firebase规则: { "rules": { ".read": true, ".write": "auth != null", "items": { "$item": { ".write": "!data.exists()", "

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

以下是我的数据结构示例(匿名,因此为“省略”值):

以下是我目前的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()"
          }
        }
      }
    }
  }
}

如何防止用户多次订阅?我需要什么规则来防止基于
用户ID
订阅者
列表中出现重复用户?

由于安全规则无法迭代记录列表以查找包含特定数据位的记录,这里的诀窍是通过允许轻松访问的ID存储记录。有一篇很好的文章提供了一些很好的见解

在这种情况下,如果您的用例允许,您可能只想切换数据结构,以便通过用户的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" }
   }
}

如果您想阻止多个具有相同用户id的条目,则每个id的记录都是唯一的。因此,使用用户id作为该记录的密钥,则只能有一个:)为什么不将其作为实际答案?因为时间是宝贵的商品,我的朋友,在我想花费时间的时候,时间并不总是可用的。:)谢谢这是我一直以来的想法,但我想知道在功能中是否有某种我缺失的
。这是一个要求的功能,我相信它会在某个时候出现在安全规则中!似乎是这样。
中的
对于任何类型的复合键规则都是至关重要的,除非它们希望每个应用程序都将复合键创建为主键。这不是不合理的,但考虑到Firebase可能的应用程序数量,肯定不是理想的。in()ops的困难在于它们非常慢。因此,在像Firebase这样的实时NoSQL环境中,通常最好以允许您按键引用数据的方式存储数据,或者在要搜索的字段上创建附加索引。在写操作方面需要做更多的工作,以使读操作的速度达到闪电般的快,并且,如果存在in()操作,我仍然希望使用响应性索引。
{
   "users": {
      "$user_id": { ".write": "auth.id === $user_id" }
   },
   "subscribers": {
      "$subscriber_id": { ".write": "auth.id === $subscriber_id" }
   }
}