假设我的数据库中有一个messages
节点,具有以下结构:
"messages": {
"$messageId": {
"text": "Hello there!",
"created_by": "$userId",
"created_at": 1501749790029
}
}
和这条规则:
"messages": {
".read": "auth != null",
"$messageId": {
".write": "auth != null",
// required fields
".validate": "newData.hasChildren(['text', 'created_by', 'created_at'])"
}
}
似乎很标准。但我的问题是,这个结构和规则允许任何用户将created_at
的值更改为任何值,对吗?属性created_at
应该是推送消息的时间戳,不应该是可编辑的。
如果我像这样重新构建我的数据库,我是否正确:
"messages": {
"$messageId": {
"text": "Hello there!",
"created_by": "$userId"
}
},
"created_at": {
"$messageId": 1501749790029
}
基本上,我会将created_at
移动到一个单独的节点,以便用户无法编辑它。然后,我将通过云功能设置一个事件触发器,当新消息被推送到created_at
时,它将自动推送messages
的时间戳。
答案 0 :(得分:0)
经过进一步研究后,我发现我可以在Firebase规则中使用.validate
和now
变量来防止无效的时间戳:
"messages": {
".read": "auth != null",
"$messageId": {
".write": "auth != null",
".validate": "newData.child('created_at').val() == now && newData.hasChildren(['text', 'created_by', 'created_at'])"
}
}
这比我想做的那么简单。惊人的。
答案 1 :(得分:0)
这样做的方法是,只有在没有以前的值时才允许设置created_at
值,here是文档
"messages": {
".read": "auth != null",
"$messageId": {
".write": "auth != null",
// required fields
".validate": "newData.hasChildren(['text', 'created_by', 'created_at'])"
"created_at": {
".write": "!data.exists()"
}
}
}
此外,我认为您可能需要验证邮件的所有者,以防止用户发布,因为其他人添加此邮件:
"created_by": {
".validate": "newData.val() == auth.uid"
}