Firebase 实时数据库给出了不正确的服务器时间偏移值

标签 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;
});

但是,问题是,在某些设备上,我会得到奇怪的值,例如 -13181 的偏移量,使其延迟了近 13 秒!因此,该设备上的 20 秒倒计时器从 7 秒开始,因为实际上偏移量要低得多。昨天,一台机器始终获得上述值(-13181),尽管它之前运行良好。同一网络上的设备是否会报告时间偏移值存在如此巨大的差异?我该如何解决这个问题?在不同设备之间同步的倒计时器对于我的应用程序非常重要。

最佳答案

添加我们昨天谈话的背景,你说:

We made a quiz application where even thousands of people can play in real time and so everyone has to see the same value on the countdown timer. Our logic is working pretty well except for the fact that rarely I get strange offset values.

您不想尽可能依赖客户端的时钟。根据人们的网络质量和与服务器的距离,已经不可避免地存在一些差异,因此正如您所看到的,添加不可靠的本地时钟可能会加剧这种情况。在线游戏的计时不是一件小事,我不会声称拥有最好的解决方案,但这里有一个尝试建议:

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

从 Admin SDK 写入数据库将如下所示:

admin.database().ref(".info/timeRemaining").set({
  time_remaining: 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_remaining 的值大于 0 时写入该位置。如果他们尝试在此之后写入,将返回错误,您可以处理在客户端。

关于Firebase 实时数据库给出了不正确的服务器时间偏移值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50361600/

相关文章:

validation - 如何使用 Firebase 规则验证该值是一个整数

android - GCM(现在的 FCM)是否有任何限制?

android - 如果应用被杀死,Firebase 不会同步离线缓存

android - 如何将 Pushid 与 Uid Firebase android 一起使用

css - 如何使用来自 Firebase 的动态图像作为背景图像?

firebase - Firestore 按两个字段排序

python-3.x - 对于 Firebase Python SDK 发生的阻塞是否有解决方法?喜欢添加完成回调吗?

android - 规则条目重复 firebase 不工作

java - 无法将 java.lang.String 类型的对象转换为 com.example.ezcompras.model.Lojas 类型

swift - 为什么添加新数据时不调用 .childAdded?火力地堡