我遇到与在 Android 应用中解析 Firestore 时间戳相关的问题。
摘要
在我的 Firebase Firestore 中,我有一组评论。每个评论都是这样的
(time is of type Timestamp)
我使用 Cloud Functions 构建了 REST API。评论端点有一个 GET 方法。共享整个代码没有意义,重要的事实是,来自该端点的响应如下所示
如您所见,响应看起来不错,一切都很好。
问题
现在,我的 Android 应用程序使用 Retrofit 与 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)]
时间戳消失了。它不为 null,但它指向纪元 (1.1.1970) 的开始。只是 0 秒、0 纳秒。我不使用任何自定义转换器或其他任何东西,只是使用“入门级改造”。
嗯,就是这样。 我不知道为什么时间戳会更改为 0,0。
如果有人能帮助我,我将非常感激。 预先感谢您。
最佳答案
您假设 Retrofit 知道如何根据服务器的默认 JSON 序列化来反序列化时间戳。它不知道该怎么做。您必须自己管理。
当您的函数序列化时间戳时,它使用文档内容的默认序列化。它正在查看 Timestamp对象并说“嘿,有一个对象,所以为了序列化它,我只需将其所有属性复制到输出中”。如果你看source for Timestamp ,您会看到它使用属性 _seconds 和 _nanoseconds 来保存时间戳的组成部分。所以,这解释了您看到的 JSON 输出。
在 Java(或 Kotlin)客户端,所有这些实际上都只是一个 Map 对象,并且类型信息消失了(而且它不会有任何帮助,因为 JavaScript 的东西并不简单地映射到 Java 的东西) )。没有人知道这是通过网络传输的时间戳类型对象。它只知道有一个带有 _seconds 和 _nanoseconds 的对象。
您需要做的就是在代码中添加一些智能功能(也许以自定义转换器的形式暗示 Retrofit),以帮助它识别 time
JSON 对象中的内容,并进行转换使用java Timestamp constructor本地时间戳对象.
或者,如果您不介意丢失几纳秒的精度,只需让函数将时间戳转换为以毫秒为单位的时间,通过网络发送,然后让客户端将其简单地转换为 java Date 对象.
您可能还想停止依赖 JavaScript Timestamp 对象的内部详细信息。由于 _seconds 和 _nanoseconds 实际上是私有(private)详细信息,因此您依赖于将来可能会发生变化的内容。 考虑使用公共(public)方法 getSeconds() 和 getNanoseconds() 中的数据显式序列化函数中的时间戳。
关于android - 使用 Retrofit 时,Firestore 时间戳为(秒 : 0, 纳秒:0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57211166/