【发布时间】:2015-10-08 18:45:18
【问题描述】:
我有一个用例,我需要用户向 Firebase 中的某个位置提供一组数据,但不能一次更改该位置的各个子节点。
举个例子,假设我有一个用户能够写入树,requests,另一个系统正在监视它以便它可以处理请求。此外,我们没有使用 .push() 生成 Firebase pushID 来唯一标识请求,而是只有一个写入请求的单一位置。结构可能如下所示:
requests: {
UserID1: {
requestParam1: "Some parameter",
requestParam2: "Another parameter"
}
}
需要明确的是,处理请求的系统会监听requests/UserID1,以便在结构发生任何变化时收到通知并处理请求。
假设requestParam1 和requestParam2 始终是必需的。每次写入UserID1 节点都需要这些参数的原因是为了防止用户仅 写入requestParam1,然后处理请求的系统不会收到实质上的请求收到 new requestParam1 和 old requestParam2。
确保在写入UserID1 时包含两个参数很简单,但我不知道如何直接停止对子节点的写入。
到目前为止,这是我的规则:
"requests": {
"$userID": {
".write": "auth !== null && newData.exists()",
".validate": "newData.hasChildren(['requestParam1', 'requestParam2'])"
"requestParam1": {
".validate": "newData.isString()"
},
"requestParam2": {
".validate": "newData.isString()"
}
"$other": {
".validate": false
}
}
}
如果我尝试在没有任何请求参数的情况下写入UserID1,它会拒绝写入——这是正确的。但是,当我直接写信给UserID1/requestParam1 时,尝试成功,这不是预期的行为。
我在两个requestParam 中都包含了".write": false 规则,但仍然允许写入。我相信这是因为父节点中的写入规则认为写入是允许的,因此会级联到子节点。根据文档,我认为没有办法解决这个问题。但是,我想我会变得聪明,让每个子节点检查newData.parent() 的子内容,如下所示:
"requests": {
"$userID": {
".write": "auth !== null && newData.exists()",
".validate": "newData.hasChildren(['requestParam1', 'requestParam2'])"
"requestParam1": {
".validate": "
newData.parent().exists() &&
newData.parent().hasChildren(['requestParam1', 'requestParam2']) &&
newData.isString()
"
},
"requestParam2": {
".validate": "
newData.parent().exists() &&
newData.parent().hasChildren(['requestParam1', 'requestParam2']) &&
newData.isString()
"
}
"$other": {
".validate": false
}
}
}
我不确定是否要添加newData.parent().exists() 检查,所以我把它扔在那里以防万一,但我认为newData().parent().hasChildren([...]) 规则会使这一切正常工作,但我错了。仍然允许写给单个孩子。
想法?
编辑 1:
我还尝试将之前在.validate 部分中的newData.hasChildren([...]) 规则移动到$userID 规则中的.write 部分,但没有成功。
【问题讨论】:
-
我认为这是不可能的。
newData包含合并的结果,因此您不能仅对更新的数据强制执行规则。 -
@AnidMonsur,“
newData包含合并结果”是什么意思?我认为newData包含要写入该位置的about 数据,以便在实际写入该位置之前可以通过.validate规则对其进行检查。 -
@AnidMonsur,感谢您指出这一点 -
newData这个名字现在比我原先想象的更令人困惑。
标签: firebase firebase-security