我正在为匿名用户设置显示名称,并希望确保新值与此设置的显示名称匹配。以下规则失败:
"name": { ".validate": "newData.val() == auth.token.name" }
这是为什么? docs表示显示名称存储在auth.token.name
。
以下是我的firebase规则的完整副本:
{
"rules": {
".read": false,
".write": false,
"messages": {
".read": true,
"$message": {
".write": "auth != null",
".validate": "newData.hasChildren(['createdAt', 'text', 'user'])",
"createdAt": { ".validate": "newData.val() == now" },
"text": { ".validate": "newData.isString() && newData.val().length > 0" },
"user": {
".validate": "newData.hasChildren(['_id', 'name'])",
"_id": { ".validate": "newData.val() == auth.uid" },
"name": { ".validate": "newData.val() == auth.token.name" },
"$other": { ".validate": false }
},
"$other": { ".validate": false }
}
}
}
}
答案 0 :(得分:2)
正如我在评论中提到的(从the documentation获取此内容):
较浅的安全规则会覆盖更深层路径的规则。儿童规则 只能授予父节点已有的额外权限 声明。他们无法撤销读取或写入权限。
这意味着您无法写入数据库,因为您已在数据库的根节点声明了.write:false
。您可能希望删除该行以具有如下结构:
{
"rules": {
".read": false,
"messages": {
".read": true,
"$message": {
".write": "auth != null",
".validate": "newData.hasChildren(['createdAt', 'text', 'user'])",
"createdAt": { ".validate": "newData.val() == now" },
"text": { ".validate": "newData.isString() && newData.val().length > 0" },
"user": {
".validate": "newData.hasChildren(['_id', 'name'])",
"_id": { ".validate": "newData.val() == auth.uid" },
"name": { ".validate": "newData.val() == auth.token.name" },
"$other": { ".validate": false }
},
"$other": { ".validate": false }
}
}
}
}
显示名称确实存储在auth.token.name
变量下。但是当你使用默认的"匿名身份验证"在规则模拟器上,它使用此默认的auth有效负载发送请求:
{
"provider": "anonymous",
"uid": "N4EbtSX5HbM9JLjsW6hWT3NWzAx1"
}
请注意,此有效负载下没有指定name
,因此auth.token.name
变量为空,安全规则拒绝写入。
您可以在模拟器上使用自定义有效负载,只需更改来自" Anonymous"到"定制"它允许你编辑有效载荷,所以你改用它:
{
"provider": "anonymous",
"uid": "N4EbtSX5HbM9JLjsW6hWT3NWzAx1",
"token":{
"name": "Mike"
}
}
使用此auth有效负载,您在评论中提供的数据有效负载应该有效:
{
"createdAt": {
".sv": "timestamp"
},
"text": "Test 1",
"user":
{
"_id": "48c83bf9-7354-4720-838f-8b68e0addd51",
"name": "Mike"
}
}