Android 当设备时钟与Firestore不同步时,我如何从Firestore服务器获取时间戳而不必担心

Android 当设备时钟与Firestore不同步时,我如何从Firestore服务器获取时间戳而不必担心,android,firebase,google-cloud-firestore,Android,Firebase,Google Cloud Firestore,这是关于这个问题的 如果我使用Timestamp.now()则会出现设备时钟与Firestore不同步以及我的时间计算不准确的情况。我想从Firestore服务器上获得准确的时间,而不会被不同步的情况所困扰。我有办法做到吗 我已经看到了FieldValue.serverTimestamp(),但是在那里我找不到使用它计算任何东西的方法,因为它的返回类型是FieldValue,如果您使用FieldValue.serverTimestamp(),我无法将其解析为Timestamp,这意味着您可以让F

这是关于这个问题的

如果我使用
Timestamp.now()
则会出现设备时钟与Firestore不同步以及我的时间计算不准确的情况。我想从Firestore服务器上获得准确的时间,而不会被不同步的情况所困扰。我有办法做到吗


我已经看到了
FieldValue.serverTimestamp()
,但是在那里我找不到使用它计算任何东西的方法,因为它的返回类型是
FieldValue
,如果您使用
FieldValue.serverTimestamp()
,我无法将其解析为
Timestamp

,这意味着您可以让Firestore为您生成一个时间戳。请注意,此时间戳完全是在服务器上生成的。它不是像文档ID那样生成的,例如在客户端上

我无法找到使用它计算任何内容的方法,因为它的返回类型是FieldValue,并且我无法将其解析为时间戳

调用FieldValue的方法时,返回的对象类型确实是
FieldValue
,但只有在需要该时间戳属性时,才将其作为参数传递。请检查如何向Cloud Firestore文档添加时间戳:

因此,如果查询数据库并获得一个文档,该文档的属性是使用
FieldValue.serverTimestamp()
设置的,则返回的对象类型为。既然你得到了一个
Date
对象,你可以用它做任何你想做的事情

然而,在Firebase实时数据库中,我们有另一种机制。所以请看这个答案:

因此,在本例中,这是完全不同的,因为我们使用的是Unix纪元以来的时间,以毫秒为单位,而不是
Date
对象

编辑:

听起来你的问题是从如何从Firestore获取时间戳开始的,但实际上只是关于如何构造一个文档,以便两个设备可以读取同一个文档。但是,要使其工作,您应该使用两个类型为
Date
的属性。一个用于设备A,一个用于设备B。请检查以下架构:

Firestore-root
   |
   --- yourCollection (collection)
        |
        --- yourDocument (document)
              |
              --- deviceA: January 24, 2020 at 3:37:59 PM UTC+3 
              |
              --- deviceB: January 25, 2020 at 3:37:59 PM UTC+3 //Timestamp
要获取
deviceA
deviceB
属性的值,请使用我在以下帖子中的答案:


现在您可以比较这两个时间戳。

一个明显但经济上不利的方法是将时间戳写入Firestore数据库,然后从那里再次读取

db.collection("TimestampChecker").document("some_string").set(new TimestampGetter()).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {

            db.collection("TimestampChecker").document("some_string").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    if(task.getResult()!=null)
                    {
                        TimestampGetter timestampGetter = task.getResult().toObject(TimestampGetter.class);
                        Date dateNow = timestampGetter.getTimestampNow();

                    }

                }
            });

        }
    });

感谢@Alex Mamo,我还希望设备B中的当前服务器时间戳位于日期对象中,以便我可以将其与设备a存储在数据库中的时间戳进行比较。我如何实现这一点?在这种情况下,您应该在需要的每个文档中存储时间戳属性。例如,如果设备A读取具有特定时间戳的文档,而设备B读取具有另一时间戳的文档,则您可以简单地比较它们。所以两个文档都应该存储该属性。设备B读取设备A存储的文档。没有单独的文档。但是为了理解设备B读取的文档是否是最近的,我需要比较文档的时间戳(由设备A设置)和设备B读取文档时生成的时间戳。在这种情况下,我需要设备B中的服务器时间戳。我如何实现这一点?我认为我的评论被误解了。2台设备未读取同一文档。正如我在评论中提到的,设备A正在存储它,设备B正在读取它。我只需要设备B中的服务器时间戳,不是来自存储的文档,而是设备B特别读取它时的服务器时间戳。我认为这将帮助您更好地理解,对吗?
public class TimestampGetter {
@ServerTimestamp
private Date timestampNow;

public TimestampGetter(Date timestampNow) {
    this.timestampNow = timestampNow;
}

public TimestampGetter() {
}

public Date getTimestampNow() {
    return timestampNow;
}

public void setTimestampNow(Date timestampNow) {
    this.timestampNow = timestampNow;
}}