Firebase数据库规则时间戳记问题 [英] Firebase Database Rules Timestamp Issue

查看:82
本文介绍了Firebase数据库规则时间戳记问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从2017年10月29日的时间推移以来,我在使用Firebase产品进行开发时遇到了一些非常奇怪的行为.

Since the time shift at the 29th of October 2017 I'm running in some really strange behaviours while developing with the firebase products.

我正在与Ionic(3)开发一个混合应用程序.当我在浏览器(移动仿真设备)中进行开发和测试时,一切正常.切换到真实设备(三星Galaxy S7,没有root,moded或其他东西)后,所有带有时间戳的数据库写入操作都会失败.

I'm developing a hybrid app with Ionic (3). While I'm developing and testing in the browser (mobile emulated device) everything works fine. As soon as I switch to my real device (Samsung Galaxy S7, no root, modded or something else), all writes to the database with a timestamp are failing.

在我的代码中,我创建一个像这样的时间戳: Date.now()

In my code I create a timestamp like this: Date.now()

在我的Firebase规则中,我通常像这样验证时间戳:

In my firebase rules I validate timestamps usualy like this:

时间戳记":{".validate":"newData.isNumber()&& newData.val()< =现在"}

对我来说,这条规则意味着要写入数据库的新数据必须是一个数字,并且新数据的值必须小于或等于当前服务器时间戳.如果这些条件之一不匹配,它将向客户端发出警告.

For me this rule means, that the new data, which wants to be written into the database, must be a number and the value of the new data must be less than or equal to the current server timestamp. If one of these conditions doesn't match, it will throw a warning at the client.

我花了一整天的时间调试代码并查找错误.当我删除(注释掉)与时间戳相关的规则上的 .validate 键时,一切正常.

I've spent a whole day debugging my code and finding the bug. When I remove (comment out) the .validate key on the timestamp related rules, everything works fine.

因此,我在firebase规则中使用了一些时间戳值.例如,我为服务器时间戳添加了一个小缓冲区,例如:(现在+ 10000)(10秒).

So I played a little bit with the timestamp values in the firebase rules. For example I added a little buffer to the server timestamp like: (now + 10000) (10secs).

突然它起作用了.我降低了该值,直到它停止在我的真实设备上运行为止.我停在(现在+ 5000)(5秒)上.

Suddenly it worked. I decreased the value until it stopped working on my real device. I stopped at (now + 5000) (5secs).

所以现在我的问题是,为什么这种行为是这样的.

So now my question is, why this behavior is the way it is.

在时间偏移之前,一切正常.以我的理解,客户端时间戳不可能领先于服务器时间戳.(除了真实设备上的本地时间是由用户自己修改的.)

Before the time shift, everything worked fine. In my understanding it couldn't be possible that a client timestamp is ahead of the server timestamps. (except the local time on the real device was modified by the user itself).

需要一些帮助,这种额外的5秒钟的解决方法似乎有点肮脏.

Looking for some help, the workaround with the additional 5 secs seems a bit dirty.

欢呼Unkn0wn0x

Cheers Unkn0wn0x

顺便说一句:每次我修改firebase规则并将其部署到服务器时,我都等待了大约五分钟.

BTW: Each time I modified the firebase rules and deployed them to the server(s), I've waited for about five minutes.

推荐答案

感谢您的注释.

我又用时间戳记打了一次时间,弄清了不想要的行为.

I've played one more time with the timestamps and figured out the unwanted behaviour.

这是代码,我已经添加到函数中,想要向数据库写入时间戳:

This is the code, I've added to my function with wants to write a timestamp to the database:

const test  = Date.now();
const test2 = new Date().getTime();
console.log('server offset: ', snap.val());
console.log('Date.now(): ', test);
console.log('new Date().getTime(): ', test2);
console.log('estimated server timestamp (new Date().getTime() + offset): ', (test2 + snap.val()));
console.log('client timestamp (Date.now() - offset): ', (test - snap.val()));

以上代码的输出:

server offset: -2427
Date.now(): 1509730244926
new Date().getTime():  1509730244926
estimated server timestamp (new Date().getTime() + offset): 1509730242499
client timestamp (Date.now() - offset): 1509730247353

这里的关键是负偏移量.我已经从客户端时间戳中减去了服务器偏移量以获得一个时间戳,该时间戳小于估计的服务器时间戳.

The crux here is the negative offset. I've substracted the server offset from the client timestamp to get a timestamp, which is smaller then the estimated server timestamp.

但是:-- + .所以我不小心将它们加在一起,而不是相互减去.

But: - and - is +. So I accidentally added them both together instead of subtract from one another.

我已经执行了几次函数,并且可以确定,从执行到执行的偏移量是不同的.一次 +77毫秒,另一次 -2427ms ,依此类推.

I've executed my function a few times and could determine, that the offset is from execution to execution different. One time +77 ms the other time -2427ms, etc..

因此,我添加了一个小代码段,以检查返回的服务器偏移量是正数还是负数,以便能够正确计算客户端时间戳.

So I added a little code snippet, which checks if the returned server offset is a postive or negative number, to be able to calculate the client timestamp correctly.

const serverOffset: number = snap.val();
let clientTimestamp: number = null;

if (Math.sign(serverOffset) === 1){
    clientTimestamp = Date.now() - serverOffset;
} else if (Math.sign(serverOffset) === -1){
    clientTimestamp = Date.now() + serverOffset;
}

clientTimestamp现在可以按预期工作.

clientTimestamp works now as expected.

如果仅将偏移量加到Firebase文档中提到的客户端时间戳上,也可以实现此行为.

This behaviour can also be achieved if the offset is just added up to the client timestamp as mentioned in the Firebase Docs.

也许应该在 Firebase文档

Maybe it should be mentioned in the Firebase Docs, that the offset can also be negative instead of just postive. This behaviour can be easily reproduced, if the local device time runs just a second later than the time, which is fetched from the internet.

但是为什么会突然发生这种情况并且从未发生过?

But why does this suddenly occur and never before?

这篇关于Firebase数据库规则时间戳记问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆