我对Firebase规则感到困惑,需要一些帮助。我google了很多,但实际上只是更加困惑,但仍然没有得到它。
假设我有一个像这样的Firebase数据库对象:
root/orders/$id
在$id
内,我有一个孩子user_id
:
root/orders/$id/user_id
现在我想要一个只允许用户阅读自己的订单的规则(但不再在现有的一次写入,如何创建新的一次),另外我希望管理员用户读/写全部随时下单。
到目前为止我想出了这个
"orders": {
"$id": {
".read": "root.child('orders').child($id).child('user_id').val() == auth.uid || root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'",
".write": "root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'"
},
".write": "root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'",
".read": "root.child('users').child(auth.uid).child('admin').val() == 'user_is_admin'",
".indexOn": ["status", "user_id"]
},
我的管理员在我的用户表中被标记为管理员:
root/users/$id/admin (== user_is_admin)
我的意图是第一部分允许与请求的auth.uid
具有相同/orders/$id/user_id
的用户阅读他们的订单以及管理员进行读写。管理部分正在运行,但我的用户由于某种原因无权访问。
第二部分是管理员对所有订单的读/写访问权限(没有特定的$id
),这也很好,加上普通用户需要写这里创建新订单。
要恢复我的规则的管理部分,但用户部分没有。 1.我的用户无法阅读自己的订单 2.我的用户无法创建新订单
如果有人可以帮助我,我会很高兴。
答案 0 :(得分:2)
规则:
以下规则应强制执行您在问题中列出的政策:
"orders": {
"$id": {
".read": "data.child('user_id').val() === auth.uid",
".write": "!data.exists() && newData.child('user_id').val() === auth.uid"
},
".write": "root.child('users').child(auth.uid).child('admin').val() === 'user_is_admin'",
".read": "root.child('users').child(auth.uid).child('admin').val() === 'user_is_admin'",
".indexOn": ["status", "user_id"]
}
请注意,Firebase安全规则会级联,因此,一旦您为orders
的管理员授予了读/写权限,您就不需要重复orders/$id
的规则。 (要记住的事情 - 虽然它不是你的规则的问题 - 但是一旦你授予了父母的许可,你就不能在孩子身上撤销它。)
orders/$id/.read
规则使用data.child
来比较user_id
和auth.uid
。这与您的规则相同,它只是稍微短一点,不包括管理员检查(级联)。
除了检查newData
(正在写入的值)是否包含user_id
之外,orders/$id/.write
规则还会检查data
(之前的值)是否存在。这将允许创建,但将拒绝更新和删除。
用户订单:
如您的评论中所述,用户无法查询orders
键下的订单列表,因为用户无权阅读其他订单用户(他们需要被过滤掉)。您可以通过按用户存储订单映射来解决问题,如下所示:
"orders": {
"order_1": {
"user_id": "user_1",
...
},
"order_2": {
"user_id": "user_1",
...
},
"order_3": {
"user_id": "user_2",
...
}
},
"ordersByUser": {
"user_1": {
"order_1": true,
"order_2": true
},
"user_2": {
"order_3": true
}
}
您可以使用Firebase的多地点更新,使维护映射变得不那么繁琐。例如,要为user_1
添加其他订单,您可以执行以下操作:
firebase.database().ref().update({
"orders/order_4": {
"user_id": "user_1",
...
},
"ordersByUser/user_1/order_4": true
});
这将允许用户获取订单ID列表(以及订单ID本身),管理员用户仍然可以获得所有订单的列表等。
此外,您应该包含一条规则,以便用户只能在ordersByUser
等下阅读自己的订单ID。