我遇到了与在Android应用中解析Firestore时间戳有关的问题。
在我的Firebase Firestore中,我有一组注释。每个评论都是这样
(时间为时间戳类型)
我已经使用Cloud Functions构建了REST API。注释端点有一个GET方法。共享整个代码没有意义,重要的事实是,来自该端点的响应看起来像这样
如您所见,响应看起来不错,一切正常。
现在,我有一个使用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。
如果有人可以帮助我,我将不胜感激。 预先谢谢你。
答案 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()中的数据在您的函数中显式序列化时间戳。