我正在创建一个应用程序,允许用户创建项目,然后允许其他用户订阅这些项目。我正在努力制定一条规则,阻止用户多次订阅某个项目。
以下是我的数据结构示例(匿名,因此是“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()"
}
}
}
}
}
}
如何阻止用户多次订阅?我需要根据subscribers
阻止userId
列表中的重复用户的规则是什么?
答案 0 :(得分:6)
由于安全规则无法迭代记录列表以找到包含某一部分数据的记录,因此这里的技巧是通过ID存储记录,以便于访问。有一篇关于denormalization的精彩文章,对这种做法提供了一些很好的见解。
在这种情况下,如果您的用例允许,您可能只想切换数据结构,以便记录按用户的id存储,而不是将ID作为值存储在记录中,如下所示:
/users/user_id/items/item_id/subscribers/user_id/
事实上,正如你在非规范化中看到的那样,你甚至可以将事情分得更远,这取决于你的数据的确切大小以及你将来如何阅读它们:
/用户/ USER_ID /项目/ USER_ID / ITEM_ID /订户/ ITEM_ID / USER_ID
使用这些格式中的任何一种,您现在都可以通过以下方式防止重复并锁定安全性:
{
"users": {
"$user_id": { ".write": "auth.id === $user_id" }
},
"subscribers": {
"$subscriber_id": { ".write": "auth.id === $subscriber_id" }
}
}