目前,Google的ServerValue.TIMESTAMP
版本会返回{".sv":"timestamp"}
,用作Firebase的指令,以便在将数据保存到Firebase服务器后使用服务器时间戳填充该字段。
但是,当您在客户端创建数据时,您还没有实际的时间戳(即用作创建日期)。在初始保存和随后的检索之后,您只能访问时间戳,我想 - 有时候太晚了,不太优雅。
Google之前:
更新:忽略此部分,因为它不正确 - 我误解了这些示例。 ServerValue.TIMESTAMP
始终返回{".sv":"timestamp"}
。
据我所知,在go-google Firebase中,似乎有一个服务器生成的时间戳可用于获取实际时间戳:
import com.firebase.client.ServerValue;
ServerValue.TIMESTAMP // eg. 1466094046
问题:
注意:
我不打算在客户端使用new Date()
,因为我一直在阅读它并不安全,但如果您认为不同,请分享您的想法。
答案 0 :(得分:25)
在写入操作中使用ServerValue.TIMESTAMP
常量时,您表示Firebase数据库服务器在执行写入操作时应确定正确的时间戳。
我们说我们运行此代码:
ref.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(dataSnapshot.getValue());
}
public void onCancelled(DatabaseError databaseError) { }
});
ref.setValue(ServerValue.TIMESTAMP);
这将执行如下:
ServerValue.TIMESTAMP
如果您使用的是ChildEventListener
而不是ValueEventListener
,则客户将在步骤3中调用onChildAdded
,在步骤8中调用onChildChanged
。
自Firebase加入Google以来,我们生成ServerValue.TIMESTAMP
的方式没有任何变化。之前有效的代码将继续有效。这也意味着first answer you linked是处理它的有效方式。
答案 1 :(得分:2)
我做的有点不同。
解决方案1:POJO中的push()
方法
由于我不想用奇怪的吸气剂或属性来混淆我的POJO,我只是在我的POJO中定义一个push()
方法,如下所示:
/**
* Pushes a new instance to the DB.
*
* @param parentNode `DatabaseReference` to the parent node this object shall be attached to
*/
fun push(parentNode: DatabaseReference) {
parentNode
.push()
.apply {
setValue(this@Pojo)
child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP)
}
}
然后我可以简单地创建一个POJO的实例并在其上调用push()
,它正确地填充了创建时间属性。
这肯定会使POJO变得不那么简单,并且涉及POJO不应该知道的逻辑。但是,如某些响应here中所述,使用@Exclude
注释和/或强制转换也需要了解存储机制。
解决方案2:助手或DatabaseReference
分机(Kotlin)
为了解决这个问题,你当然也可以在帮助器中创建一个pushTask(task: Task)
方法,或者 - 如果使用Kotlin - 一个扩展方法,例如DatabaseReference
看起来像这样:
fun DatabaseReference.push(pojo: Pojo) {
push()
.apply {
setValue(pojo)
child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP)
}
}
现在看着它,我开始认为我更喜欢第二种方法(如果我有Kotlin可供我使用 - 我不喜欢帮手)。但这可能只是一个品味问题。 ;)