Firebase实时数据库提供的服务器时间偏移值不正确

Firebase实时数据库提供的服务器时间偏移值不正确,firebase,firebase-realtime-database,Firebase,Firebase Realtime Database,我在PWA中使用以下代码根据文档计算Firebase实时数据库服务器的客户端时钟偏差:- var offsetRef = firebase.database().ref(".info/serverTimeOffset"); offsetRef.on("value", function(snap) { var offset = snap.val(); var estimatedServerTimeMs = new Date().getTime() + offset; }); 然而,问题是

我在PWA中使用以下代码根据文档计算Firebase实时数据库服务器的客户端时钟偏差:-

var offsetRef = firebase.database().ref(".info/serverTimeOffset");
offsetRef.on("value", function(snap) {
  var offset = snap.val();
  var estimatedServerTimeMs = new Date().getTime() + offset;
});

然而,问题是,在一些设备上,我得到了奇怪的值,比如偏移量为-13181,使其缩短了近13秒!因此,该设备上20秒的倒计时从7秒开始,因为实际上偏移量要低得多。昨天,一台机器持续获得上述值(-13181),尽管它在早些时候工作正常。同一网络上的设备会报告时间偏移值的巨大差异,这有什么原因吗?如何解决此问题?跨不同设备同步的倒计时计时器对我的应用程序非常关键。

添加我们昨天对话的上下文,您说:

我们制作了一个测验应用程序,让成千上万的人都可以在里面玩 实时,因此每个人都必须在倒计时时看到相同的值 计时器。我们的逻辑运行得很好,除了 我很少得到奇怪的偏移值

尽可能地,你不想依赖客户的时钟。基于人们的网络质量和与服务器的距离,已经不可避免地存在一些差异,因此正如您所看到的,添加不可靠的本地时钟可能会加剧这种情况。在线游戏的时间安排并非易事,我不会声称自己有最好的解决方案,但这里有一个建议可以尝试:

有一个真相来源,可能是一个服务器,它跟踪游戏中剩余的时间并在数据库中更新。您可以使用从服务器访问数据库,这可能就是您现在输入时间戳的方式

从Admin SDK写入数据库的操作如下所示:

admin.database().ref(".info/timeRemaining").set({
  time_remaining: time_remaining
});
其中,
剩余时间
将是您每秒更新的时间

然后在客户机上,不跟踪偏移量,只剩下剩余的时间

var offsetRef = firebase.database().ref(".info/timeRemaining");
offsetRef.on("value", function(snap) {
  var offset = snap.val();
  // do what you will
});
然后,您可以在客户端上设置在0结束游戏的规则。当然,开发人员可以找到解决这个问题的方法,所以如果可能的话,最好包括一个服务器检查。如果客户机也在向数据库写入数据,但您不希望他们能够在超过时间限制后写入数据,那么一个选项是使用规则。现在,根据您的数据结构,您的规则看起来会有所不同。我只是想把写操作应用到
“.info”
的任何孩子身上,这可能不是您所需要的

{
  "rules": {
    ".info": {
      "$info": {
        ".read": "auth != null",
        // writes can only happen before the timer reaches 0
        ".write": "data.parent().child('time_remaining').val() > 0"
      }
    }
  }
}

此规则仅允许用户在
time\u remaining
的值大于0时写入该位置。如果他们在此之后尝试写入,将返回一个错误,您可以处理在客户端上显示此错误。

谢谢Jen!一个问题似乎是每秒都会有大量的读取,时钟可能不会平稳运行。我正在尝试在中讨论的方法。在我的例子中,我将开始时间设置为firebase.database.ServerValue.TIMESTAMP,然后取(本地时间+偏移量)和开始时间之间的差来获得秒数。我是否应该找出另一种计算偏移量的方法,而不是使用.info/serverTimeOffset?我的代码中有一个回归错误,因为忽略了哪个偏移量。我的应用程序工作正常。我很高兴我还有另一个倒计时的解决方案。@NikhilAgarwal我也有同样的问题。你能发布完整的代码来看看它是如何与firebase函数和firebase客户端一起工作的吗?我的代码中有一个回归错误,因为偏移量被忽略了。我的应用程序工作正常。