2017-11-03 15 views
1

2017年10月29日のタイムシフト以来、私はfirebase製品で開発中にいくつかの本当に奇妙な動作をしています。Firebaseデータベースルールタイムスタンプの問題

私はIonic(3)でハイブリッドアプリを開発しています。私が開発しているブラウザ(モバイルエミュレートされたデバイス)でテストしている間、すべて正常に動作します。実際のデバイス(Samsung Galaxy S7、ルートなし、moddedなど)に切り替えると、タイムスタンプ付きのデータベースへのすべての書き込みが失敗します。私はこのようなタイムスタンプを作成して自分のコードで

:私はusualyこのようなタイムスタンプを検証する私のfirebaseルールでDate.now()

:私にとって

"timestamp": { ".validate": "newData.isNumber() && newData.val() <= now" }

このルールは意味、新しいデータつまり、データベースに書き込まれる必要があるデータは数値でなければならず、新しいデータの値は現在のサーバーのタイムスタンプ以下でなければなりません。これらの条件のいずれかが一致しない場合、クライアントに警告が表示されます。

私は一日をかけて自分のコードをデバッグしてバグを見つけました。タイムスタンプに関連するルールの.validateキーを削除(コメントアウト)すると、すべて正常に動作します。

私はfirebaseルールのタイムスタンプ値で少し演奏しました。たとえば、私はサーバーのタイムスタンプに少しのバッファーを追加しました:(now + 10000)(10秒)。

突然それが働いた。私はそれが私の実際のデバイスで動作しなくなるまで値を減らしました。私は(now + 5000)(5秒)で止まった。

ここで私の質問は、なぜこの動作がそれであるかということです。

タイムシフトの前に、すべて正常に機能しました。私の理解では、クライアントのタイムスタンプがサーバーのタイムスタンプよりも先にある可能性はありませんでした。 (実際のデバイス上の現地時間は、ユーザー自身によって変更されたことを除いて)。

いくつかの助けを借りて、さらに5秒で回避策が少し汚れているようです。ところで

乾杯 Unkn0wn0x

:私はfirebaseルールを変更し、サーバ(群)にそれらを展開するたびに、私は約5分間待っていました。

+0

[クライアントのクロックスキュー](https://firebase.google.com/docs/database/web/offline-capabilities#clock-skew)を確認するためのコードを追加することで、いくつかの洞察を得るかもしれません –

答えて

0

ありがとうございます。

私はタイムスタンプでもう一度試して、望ましくない動作を見つけました。

これはコードですが、私は、データベースへのタイムスタンプを書きたいと私の機能を追加しました:

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 

ここ核心負のオフセットです。私はタイムスタンプを得るためにクライアントのタイムスタンプからサーバのオフセットを差し引いた。これは推定されたサーバのタイムスタンプよりも小さい。

しかし、-およびは+です。だから私は誤ってお互いを引くのではなく、一緒に両方を加えました。

私は自分の関数を数回実行しましたが、オフセットは実行から実行まで異なっていると判断できました。ワンタイム+77 ms他の時間-2427ms、など。

は、だから私は、オフセット返さサーバはポジティブまたは負の数であれば、正しくクライアントのタイムスタンプを計算することができるように、チェックする小さなコードスニペットを追加しました。

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は期待どおりに動作します。

この動作は、Firebase Docsに記載されているように、クライアントのタイムスタンプにオフセットが追加された場合にも達成できます。

Firebase Docsではオフセットをポスタティブではなくマイナスにすることもできます。この動作は、ローカルデバイスの時間がインターネットからフェッチされた時間よりわずか1秒遅れて実行されると容易に再現できます。

しかし、なぜこれは突然発生し、これまでにないのですか?

+0

私の経験は、クロックスキューは繰り返し実行すると非常に安定します。 320 +/- 10ミリ秒。 +77から-2427までのバリエーションのレポートを見ることに驚いています。 –

関連する問題