使用改造时,Firestore时间戳为(秒:0,纳秒:0)

时间:2019-07-25 23:05:42

标签: android firebase google-cloud-firestore google-cloud-functions retrofit

我遇到了与在Android应用中解析Firestore时间戳有关的问题。

摘要

在我的Firebase Firestore中,我有一组注释。每个评论都是这样

comment

  

(时间为时间戳类型)

我已经使用Cloud Functions构建了REST API。注释端点有一个GET方法。共享整个代码没有意义,重要的事实是,来自该端点的响应看起来像这样

comment_response

如您所见,响应看起来不错,一切正常。

问题

现在,我有一个使用Retrofit的Android应用与API进行通信。它向上述端点发出请求并获得响应(响应为<List<CommentResponse>>)。

import com.google.firebase.Timestamp

data class CommentResponse(
    val placeId: String,
    val userUid: String,
    val userDisplayName: String,
    val userPhotoUrl: String,
    val time: Timestamp,
    val text: String
)

但是当我执行Log.d(response.body)时,我得到了(我剪切了不重要的数据)

[CommentResponse(placeId=opactwo, userUid=e09E...82, userDisplayName=Bartek Pacia, userPhotoUrl=https: .../photo.jpg, time=Timestamp(seconds=0, nanoseconds=0), text=This place is very beautiful :D)]

时间戳消失了。它不是空值,而是指向纪元(1.1.1970)的开始。只需0秒,0纳秒。我不使用任何自定义转换器,而仅使用“初学者级改装”。

是的,就是这样。 我不知道为什么时间戳更改为0,0。

如果有人可以帮助我,我将不胜感激。 预先谢谢你。

1 个答案:

答案 0 :(得分:1)

您假设Retrofit知道如何基于服务器的默认JSON序列化对时间戳进行反序列化。它不知道该怎么做。您将必须自己进行管理。

当函数序列化时间戳时,它将使用文档内容的默认序列化。它正在查看Timestamp对象,并说:“嘿,有一个对象,因此要对其进行序列化,我将其所有属性复制到输出中”。如果您查看source for Timestamp,将会看到它使用_seconds和_nanoseconds属性来保存时间戳的组成部分。因此,这说明了您看到的JSON输出。

在Java(或Kotlin)客户端,实际上只是一个Map对象,所有类型信息都消失了(这对JavaScript并不能简单地映射到Java东西没有帮助。 )。没有人知道这是一个跨越电线的Timestamp类型的对象。它所知道的是,有一个对象具有_seconds和_nanoseconds。

您需要做的是在代码中添加一些技巧(也许以自定义转换器的形式向Retrofit提示),以帮助其识别该time JSON对象中的内容,并将其转换为使用java Timestamp constructor在本地创建时间戳记对象。

或者,如果您不介意损失几纳秒的精度,只需将函数将Timestamp转换为以毫秒为单位的时间,通过电线发送,然后让客户端将其简单地转换为java Date对象

您可能还想根据JavaScript Timestamp对象的内部详细信息停止操作。由于_seconds和_nanoseconds实际上是私有详细信息,因此您依赖将来可能会更改的内容。 考虑使用公共方法getSeconds()和getNanoseconds()中的数据在您的函数中显式序列化时间戳。