Firebase的服务器时间戳与正确时间不一致。

3

我正在尝试使用firebase-server-timestamp来向用户展示他/她何时将订单发送给我们。

我遇到的问题是,server-timestamp显示了错误的时间(例如:当前时间为12:30,但时间戳显示为12:15),这是怎么可能的呢?

Android代码

data class MyTimestampPOJO(
    val date: Timestamp = Timestamp.now(), // wrong, 15 minutes too early
)

数据库截图(发送时间为12:50而不是12:35)

enter image description here

将数据写入Firestore

suspend fun sendEmail() {
    val data = MyTimestampPOJO()
    FirebaseFirestore..getInstance().collection("orders_service").add(data).await()
}

读取数据

export const dbOrderServiceOnCreated = functions
   .region("europe-west1")
   .firestore
   .document("orders_service/{id}")
   .onCreate((snapshot, context) => {
        const data = snapshot.data()
        const date = convertTimestampToDate(data.date)

        return Promise.resolve()
    }

function convertTimestampToDate(stamp: firestore.Timestamp): string {
    return new Intl.DateTimeFormat('de-De', { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' }).format(stamp.toDate())
}

我正在测试firebase-emulator中的内容。我的手机时间是正确的(即使它并不重要,因为server-timestamp独立于手机时间,正如它应该)。

编辑答案

正如@DIVYANSHU SAHU和@MiniDev99指出的那样,我有几个问题。首先,不应该使用

data class MyTimestampPOJO(val date: Timestamp = Timestamp.now())

应当使用

data class MyTimestampPOJO(@ServerTimestamp val date: Timestamp? = null)

这是因为在文档写入数据库时,第二个POJO-Timestamp将被填充:

用于标记时间戳字段的注释,以填充服务器时间戳。如果要写入的POJO包含@ServerTimestamp注释字段的null值,则会用服务器生成的时间戳替换该null值。

此外,每个函数都可以有自己的区域(可调用和基于事件)。因此,应始终将函数区域指定为其特定区域(例如,我们自动分配了我的函数区域,但我住在欧洲)。
export const dbOrderServiceOnCreated = functions
    .region("europe-west1") // IMPORTANT!!!!
    .firestore
    ...

请编辑您的问题并展示将数据写入Firestore的方式。 - Alex Mamo
1
我认为我知道发生了什么,您的服务器位于另一个时区,而您的手机位于另一个时区,因此当服务器时间为12:00时,根据您的时区,您的时间会提前或延后15分钟。因此,您只需根据前端时区相应地添加或减去时间。https://stackoverflow.com/a/66079801/13139719 这个答案讨论了这个问题。 - DIVYANSHU SAHU
2个回答

3
你可以保存Firebase服务器的时间和日期,而不是手机的日期和时间,因为如果你保存的是手机的时间戳,那么时间会不同,因为每个手机的时间都不同。
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Map map = new HashMap();
map.put("timestamp", ServerValue.TIMESTAMP);
ref.child("yourNode").updateChildren(map);

我没有“ServerValue.TIMESTAMP”。我正在使用FirebaseFirestore,它只有“Timestamp.now()”。 - Andrew
我将 val date: Timestamp = Timestamp.now() 更改为 @ServerTimestamp val date: Timestamp? = null,问题得到了解决。 - Andrew

1

我不确定,但我认为我以前见过这种情况发生,在那种情况下(但我可能错了),我认为模拟器/手机上运行的应用程序设置了错误的日期/时间。因此,当前时间戳也是错误的。


我已经检查过了。模拟器手机的时间戳是正确的。例如:我发送合同,模拟器时间是13:00,但时间戳显示12:50。 - Andrew
此外,时间戳与手机时间无关,因为它们彼此独立。 - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接