如何使用 Firebase 服务器时间戳生成创建日期?
Posted
技术标签:
【中文标题】如何使用 Firebase 服务器时间戳生成创建日期?【英文标题】:How to use the Firebase server timestamp to generate date created? 【发布时间】:2016-10-18 07:29:35 【问题描述】:目前,Google 的 ServerValue.TIMESTAMP
版本会返回 ".sv":"timestamp"
,它被用作 Firebase 的指令,一旦您将数据保存到 Firebase 服务器,就会使用服务器时间戳填充该字段。
但是,当您在客户端创建数据时,您还没有实际的时间戳可供使用(即用作创建日期)。您只能在初始保存和随后的检索之后访问时间戳,我想这有时为时已晚而且不是很优雅。
在 Google 之前:
更新:忽略此部分,因为它不正确 - 我误解了示例。 ServerValue.TIMESTAMP
总是返回 ".sv":"timestamp"
。
据我所知,在谷歌之前的 Firebase 中似乎有一个服务器生成的时间戳可用,可让您获取实际的时间戳:
import com.firebase.client.ServerValue;
ServerValue.TIMESTAMP // eg. 1466094046
(ref 1, ref 2)
问题:
-
这种保存/检索是在我的模型实例上获取服务器生成的创建日期的唯一方法吗?
如果可以,您能否提出一种实现这种模式的方法?
我是否正确理解 ServerValue.TIMESTAMP 已随着 Google 收购 Firebase 而发生变化? 更新:不,@FrankvanPuffelen 回复说收购期间没有任何变化。
注意:
我不考虑在客户端使用 new Date()
,因为我一直在阅读它不安全,但如果您有不同的想法,请分享您的想法。
【问题讨论】:
firebaser here 自从我们加入 Google 以来,我们生成ServerValue.TIMESTAMP
的方式没有任何改变。以前有效的代码将继续有效。如果您的代码不起作用,请将重现问题的最少代码添加到您的问题中。
@FrankvanPuffelen 我误解了旧的例子,谢谢。 ServerValue.TIMESTAMP
总是返回 ".sv":"timestamp"
。我不是指不起作用的代码,只是关于如何正确使用该服务器时间戳来处理 date created 的理论问题
【参考方案1】:
当您在写入操作中使用 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
写了一个值
Firebase 客户端立即触发一个值事件,其时间戳近似于它将写入服务器的时间戳
您的代码会打印该值
写入操作被发送到 Firebase 服务器
Firebase 服务器确定实际时间戳并将值写入数据库(假设没有安全规则失败)
Firebase 服务器将实际时间戳发送回客户端
Firebase 客户端针对实际值引发值事件
您的代码会打印该值
如果您使用的是ChildEventListener
而不是ValueEventListener
,那么客户端将在第 3 步中调用onChildAdded
,在第 8 步中调用onChildChanged
。
自 Firebase 加入 Google 以来,我们生成 ServerValue.TIMESTAMP
的方式没有任何变化。以前有效的代码将继续有效。这也意味着first answer you linked 是一种有效的处理方式。
【讨论】:
是否可以在 ServerValue.TimeStamp 上添加修改,例如我想将其设为 Date()。之后查询将按孩子排序,例如今天,明天 @mehmet 你找到方法了吗?我正在根据服务器时间戳存储“分数”,我需要获取最近 48 小时内存储的“分数”;因为每个设备的当地时间不同 很遗憾没有【参考方案2】:我的做法有点不同。
解决方案一: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)
然后我可以简单地创建 POJO 的一个实例并在其上调用 push()
以正确填充创建时间属性。
这肯定会让 POJO 变得不那么简单,并且涉及 POJO 不应该知道的逻辑。但是,使用 @Exclude
注释和/或转换(如某些响应 here 中所述)也需要了解存储机制。
解决方案 2:Helper 或 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 - 我不喜欢助手)。但这可能只是口味问题。 ;)
【讨论】:
以上是关于如何使用 Firebase 服务器时间戳生成创建日期?的主要内容,如果未能解决你的问题,请参考以下文章
如何在android中将日期转换为firebase时间戳格式
如何从 Firebase 的 iOS API 获取服务器时间戳?
如何将选定的时间戳转换为firebase服务器时间戳android