Javascript Firebase数据库-防止写入指定路径以外的所有路径
我有firebase设置和工作(提交表单数据客户端),但我试图添加一些规则和验证。只有一个路径,它是可公开写入的,但我想将其锁定,以便无法创建其他路径 我想我可以做到:Javascript Firebase数据库-防止写入指定路径以外的所有路径,javascript,firebase,firebase-realtime-database,firebase-security,Javascript,Firebase,Firebase Realtime Database,Firebase Security,我有firebase设置和工作(提交表单数据客户端),但我试图添加一些规则和验证。只有一个路径,它是可公开写入的,但我想将其锁定,以便无法创建其他路径 我想我可以做到: { "rules": { "myPath": { ".read": "auth != null", ".write": true, ".validate": "newData.hasChildren([ 'name', 'email', 'agree
{
"rules": {
"myPath": {
".read": "auth != null",
".write": true,
".validate": "newData.hasChildren([
'name',
'email',
'agreeTerms',
'results',
])",
"name": {".validate": "newData.isString() && newData.val().length <
100"},
"email": {".validate": "newData.isString()"},
"agreeTerms": {".validate": "newData.isString() && newData.val().length < 4"}
},
".read": "auth != null",
".write": "auth != null"
}
}
有效负载只是一个包含hasChildren字段的对象
可重现问题的有效负载对象:
const payload = {
agreeTerms: 'yes',
email: 'terry@bingbong.com',
name: 'Terry Bing',
results: {
q1: { score: 0, time: 0 },
q2: { score: 0, time: 0 },
q3: { score: 0, time: 0 },
q4: { score: 0, time: 0 },
q5: { score: 0, time: 0 },
},
};
您正在调用push(…)
,它在您调用它的引用下创建一个新的子节点。因此属性(agreeTerms
,email
等)最终位于/myPath/-LK….
下,验证希望它们立即位于/myPath
下
两种可能的修复方法:使用设置(…)
或修改规则以包含推送ID
第一个很简单:
const dataBase = firebase.database().ref('/myPath');
dataBase.set(payload, error => {
if (error) {
return console.log(`Error writing to database ${error}`);
}
});
由于这将调用set(…)
而不是push,因此数据直接写入myPath
下,并与验证规则相匹配
第二种解决方案是使您的安全规则与代码匹配,这意味着您需要在规则中执行较低级别的验证。由于您事先不知道由push()
生成的ID是什么,因此需要将其设置为所谓的“通配符规则”:
{
“规则”:{
“myPath”:{
“$pushId”:{
“.write”:正确,
“.validate”:“newData.haschilds(['name'、'email'、'agreeTerms'、'results'])”,
“name”:{.validate”:“newData.isString()&&newData.val().length<
100"},
“电子邮件:{.validate:”newData.isString()“},
“agreeTerms”:{.validate”:“newData.isString()&&newData.val().length<4”}
}
},
“.read”:“auth!=null”,
.write:“auth!=null”
}
}
在上面的示例中:
$pushId
下的规则适用于/myPath
下的任何子节点。此逻辑适用于名称以$
开头的任何规则。因此,它不必被称为$pushId
,它也可以是$child
或任何以$
开头的东西。您能用硬编码的对象为有效负载进行复制吗?如果是这样,请更新您的问题以显示。@FrankvanPuffelen是的,我已将其添加到问题中。非常感谢!效果很好。我是firebase的新手,所以这确实帮助我更好地理解它。
const dataBase = firebase.database().ref('/myPath');
dataBase.set(payload, error => {
if (error) {
return console.log(`Error writing to database ${error}`);
}
});
{
"rules": {
"myPath": {
"$pushId": {
".write": true,
".validate": "newData.hasChildren(['name', 'email', 'agreeTerms', 'results'])",
"name": {".validate": "newData.isString() && newData.val().length <
100"},
"email": {".validate": "newData.isString()"},
"agreeTerms": {".validate": "newData.isString() && newData.val().length < 4"}
}
},
".read": "auth != null",
".write": "auth != null"
}
}