Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何使用Firebase服务器时间戳生成创建日期?_Android_Firebase_Timestamp_Firebase Realtime Database - Fatal编程技术网

Android 如何使用Firebase服务器时间戳生成创建日期?

Android 如何使用Firebase服务器时间戳生成创建日期?,android,firebase,timestamp,firebase-realtime-database,Android,Firebase,Timestamp,Firebase Realtime Database,目前,谷歌版本的ServerValue.TIMESTAMP返回{.sv:“TIMESTAMP”},当您将数据保存到Firebase服务器时,它被用作Firebase的一个指令,用服务器时间戳填充该字段 但是,当您在客户端创建数据时,您还没有实际的时间戳(即用作创建日期)。只有在初始保存和随后的检索之后,您才能访问时间戳,我想这有时太晚了,也不是很优雅 在谷歌之前: 更新:忽略此部分,因为它不正确-我误解了示例ServerValue.TIMESTAMP始终返回{.sv:“TIMESTAMP”}

目前,谷歌版本的
ServerValue.TIMESTAMP
返回
{.sv:“TIMESTAMP”}
,当您将数据保存到Firebase服务器时,它被用作Firebase的一个指令,用服务器时间戳填充该字段

但是,当您在客户端创建数据时,您还没有实际的时间戳(即用作创建日期)。只有在初始保存和随后的检索之后,您才能访问时间戳,我想这有时太晚了,也不是很优雅


在谷歌之前:

更新:忽略此部分,因为它不正确-我误解了示例
ServerValue.TIMESTAMP
始终返回
{.sv:“TIMESTAMP”}

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

导入com.firebase.client.ServerValue;
ServerValue.TIMESTAMP//例如1466094046
(,)


问题:

  • 这样的保存/检索是在我的模型实例上获取服务器生成的创建日期的唯一方法吗
  • 如果是,您能提出一种实现这种模式的方法吗
  • 我对ServerValue.TIMESTAMP的理解是否正确?随着谷歌收购Firebase,ServerValue.TIMESTAMP发生了变化?更新:没有,@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);
    
    这将按如下方式执行:

  • 您附加了一个侦听器
  • 您可以使用
    ServerValue.TIMESTAMP
  • Firebase客户端立即触发一个值事件,其时间戳近似于它将在服务器上写入的时间戳
  • 您的代码将打印该值
  • 写入操作被发送到Firebase服务器
  • Firebase服务器确定实际时间戳并将值写入数据库(假设没有安全规则失败)
  • Firebase服务器将实际时间戳发送回客户端
  • Firebase客户端为实际值引发值事件
  • 您的代码将打印该值
  • 如果您使用的是
    ChildEventListener
    而不是
    ValueEventListener
    ,则客户端将在步骤3中调用
    onchildaded
    ,在步骤8中调用
    onChildChanged


    自Firebase加入Google以来,我们生成
    ServerValue.TIMESTAMP
    的方式没有任何改变。以前有效的代码将继续有效。这也意味着是一种有效的处理方法。

    当您在写入操作中使用
    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中调用
    onchildaded
    ,在步骤8中调用
    onChildChanged


    自Firebase加入Google以来,我们生成
    ServerValue.TIMESTAMP
    的方式没有任何改变。以前有效的代码将继续有效。这也意味着这是一种有效的处理方法。

    我的做法有点不同

    解决方案1:
    push()
    POJO中的方法

    由于我不想用奇怪的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)
            }
    }
    
    fun DatabaseReference.push(pojo: Pojo) {
        push()
        .apply {
            setValue(pojo)
            child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP)
        }
    }
    
    然后,我可以简单地创建POJO的一个实例,并在其上调用
    push()
    ,从而正确填充creation time属性

    这无疑使POJO变得不那么简单,并且涉及POJO不应该知道的逻辑。但是,使用一些响应中概述的
    @Exclude
    注释和/或强制转换也需要了解存储机制

    解决方案2:Helper或
    数据库参考
    扩展(Kotlin)

    为了克服这个问题,您当然也可以在助手中创建一个
    pushTask(task:task)
    方法,或者(如果使用Kotlin)一个扩展方法,例如
    DatabaseReference
    ,它可以如下所示:

    /**
     * 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)
            }
    }
    
    fun DatabaseReference.push(pojo: Pojo) {
        push()
        .apply {
            setValue(pojo)
            child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP)
        }
    }
    

    现在看着它,我开始觉得我实际上更喜欢第二种方法(如果我有Kotlin在我的支配下-我不喜欢助手)。但这可能只是品味的问题

    我的做法有点不同

    解决方案1:
    push()
    POJO中的方法

    由于我不想用奇怪的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)
            }
    }
    
    fun DatabaseReference.push(pojo: Pojo) {
        push()
        .apply {
            setValue(pojo)
            child(Pojo.CREATED_AT_KEY).setValue(ServerValue.TIMESTAMP)
        }
    }
    
    然后,我可以简单地创建一个POJO实例,并在其上调用
    push()
    ,从而正确填充cre