如何使用Firebase服务器时间戳生成date?

目前,Google版本的ServerValue.TIMESTAMP返回{".sv":"timestamp"} ,一旦您将数据保存到Firebase服务器,该版本将作为Firebase的指令使用服务器时间戳填充该字段。

但是,当您在客户端创build数据时,您还没有实际的时间戳(即用作创builddate)。 在初始保存和随后的检索之后,您只能访问时间戳,我想 – 这有时为时已晚,不够优雅。


Google之前:

更新:忽略这一部分,因为它是不正确的 – 我误解了这些例子。 ServerValue.TIMESTAMP总是返回{".sv":"timestamp"}

据我所知,在谷歌Firebase之前,似乎有一个服务器生成的时间戳,允许您获取实际的时间戳:

 import com.firebase.client.ServerValue; ServerValue.TIMESTAMP // eg. 1466094046 

( 参考文献1 , 参考文献2 )


问题:

  1. 这样的保存/检索是获得我的模型实例上的服务器生成的创builddate的唯一方法吗?
  2. 如果是的话,你能提出一个实施这种模式的方法吗?
  3. 我是否正确理解ServerValue.TIMESTAMP随着Google收购Firebase而改变? 更新:不,@FrankvanPuffelen回复说,收购过程中没有任何变化。

注意:

我不考虑在客户端使用new Date() ,因为我一直在阅读它是不安全的,但如果你认为不同,请分享你的想法。

在写入操作中使用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); 

这将执行如下:

  1. 你附加一个监听器
  2. 你用ServerValue.TIMESTAMP写一个值
  3. Firebase客户端会立即触发一个值事件,并将其大致写入服务器的时间戳
  4. 你的代码打印这个值
  5. 写入操作被发送到Firebase服务器
  6. Firebase服务器确定实际的时间戳并将值写入数据库(假设没有安全规则失败)
  7. Firebase服务器会将实际的时间戳发送回客户端
  8. Firebase客户端会为实际价值提出价值事件
  9. 你的代码打印这个值

如果您使用ValueEventListener而不是ValueEventListener ,则客户端将在步骤3中调用onChildAdded ,并在步骤8中调用onChildAdded

自从FirebasejoinGoogle后,我们生成ServerValue.TIMESTAMP的方式没有任何变化。 以前工作的代码将继续工作。 这也意味着你链接的第一个答案是一个有效的方法来处理它。

我做的有点不同

解决scheme1:POJO中的push()方法

因为我不想用奇怪的getter或属性来混淆我的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) } } 

然后,我可以简单地创build一个POJO的实例,并调用push()来正确地填充创build时间属性。

这绝对使得POJO不那么简单,并且涉及POJO不应该知道的逻辑。 然而,使用@Exclude注释和/或强制转换在这里的一些响应中概述也需要知道存储机制。

解决scheme2:Helper或DatabaseReference扩展(Kotlin)

为了克服这个问题,你当然也可以在助手中创build一个pushTask(task: Task)方法,或者 – 如果使用Kotlin – 一个扩展方法,例如DatabaseReference ,它看起来像这样:

 fun DatabaseReference.push(pojo: Pojo) { push() .apply { setValue(pojo) child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP) } } 

现在看,我觉得我其实更喜欢第二种方法( 如果我有Kotlin在我手中 – 我不喜欢帮手)。 但这可能只是一个口味问题。 ;)