如何使用 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

如何使用 Firestore 在 Cloud Functions for Firebase 中获取服务器时间戳?

如何以毫秒为单位获取firebase服务器的当前时间戳?

如何使用firestore admin nodejs sdk设置服务器时间戳?