如果我们不希望它们可编辑,那么在Firebase中存储时间戳的正确方法是什么?

时间:2017-08-03 09:24:41

标签: firebase firebase-realtime-database

假设我的数据库中有一个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的时间戳。

2 个答案:

答案 0 :(得分:0)

经过进一步研究后,我发现我可以在Firebase规则中使用.validatenow变量来防止无效的时间戳:

"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"
 }