android - 使用 Retrofit 时,Firestore 时间戳为(秒 : 0, 纳秒:0)

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

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

摘要

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

comment

(time is of type Timestamp)

我使用 Cloud Functions 构建了 REST API。评论端点有一个 GET 方法。共享整个代码没有意义,重要的事实是,来自该端点的响应如下所示

comment_response

如您所见,响应看起来不错,一切都很好。

问题

现在,我的 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/

相关文章:

android - 如何获取 TextField (Jetpack Compose) 的光标位置?

ios - 如何让 Firebase 自动删除超过 30 分钟的值

Javascript:将数据从 Firebase DB 加载到生成的输入字段中

angular - Angular Firestore 分页

javascript - 追加到 Firestore 中的数组字段

android - 如何将 int 数组添加到共享首选项中?

java - dex2jar 和 JD-GUI 标签语句

Firebase 安全规则 : Allow if user uid exists in a collection as a document

java - 如何将新对象添加到已创建的列表中?

android - 如何在 android 中获取有效的 firebase token ?