我有以下数据库架构:
{
"events": {
"$eventId": {
"eventTitle": "Go shopping",
"participants": {
"0": {
"id": "0",
"name": "John Smith"
},
"1": {
"id": "1",
"name": "Jason Black"
}
}
}
}
}
这是一系列事件,每个事件都有一个参与者列表。如何制作数据库规则,其中:
这是我在规则方案中的尝试:
{
"rules": {
"events": {
".read": true,
"$eventKey": {
"eventTitle": {
".validate": "newData.isString() && newData.val().length < 100"
},
"participants": {
".read": "root.child('users/'+auth.uid+'/role').val() === 'ADMIN'",
".validate": "newData.hasChildren()",
"$participantKey": {
".read": "($participantKey === auth.uid || root.child('users/'+auth.uid+'/role').val() === 'ADMIN')",
"id": {
".validate": "newData.val() === $participantKey"
},
"name": {
".validate": "newData.isString() && newData.val().length < 100"
}
}
}
}
}
}
}
不有效,因为当我阅读事件列表时,它不会尊重.read
和participants
字段中的$participantKey
约束。它只是一直检索完整的参与者名单。
@ 修改
换句话说。我有这个简化的规则:
{
"events": {
".read": true,
"$eventKey": {
"participants": {
".read": false
}
}
}
}
当我查询:events/{eventKey}/participants
时,即使participants
读取标志设置为false
,我仍然会收到参与者的对象。
但是,当我从.read
删除 events
标记时,检索数据会在.read
中显示participants
标记。
@的 EDIT2
授予读取位置权限的.read规则也允许读取该位置的任何后代,即使后代有自己的.read规则失败。
我现在的问题是,如何省略这条规则?
答案 0 :(得分:1)
Firebase permissions cascade向下。一旦您在JSON树中为某个级别的用户授予了权限,就无法在树的较低级别撤消该权限。
这意味着这些规则不起作用:
{
"events": {
".read": true,
"$eventKey": {
"participants": {
".read": false
}
}
}
}
Firebase会忽略".read": false
。
相反,您必须以允许安全要求的方式构建数据。这是通过完全分离具有不同安全要求的数据类型来完成的。
{
"events": {
".read": true,
"$eventKey": {
"participants": {
".read": false
}
}
}
"eventparticipants": {
".read": false
"$eventKey": {
/* This is where you store the participants */
}
}
}
因此,您有两个顶级列表:events
和eventparticipants
。列表对其下的对象使用相同的键:事件ID。但由于这些是两个顶级列表,一个可以公开阅读而另一个更受限制。
答案 1 :(得分:0)
Firebase文档建议在向数据库添加数据时不要使用数组。您的代码中的主要问题是您使用的是一个数组,这对Firebase来说是一种反模式。
Firebase建议不要使用数组的原因之一是它使安全规则无法编写,这就是您的情况。
由于Firebase是一个NoSQL数据库,并且因为它的结构是密钥和valeu对,因此解决方案是使用Map
和而不是数组。更改在数据库中添加数据的方式,您的问题就会得到解决。