私は、すべてのユーザーがアプリを開くたびにアプリの訪問をカウントしたかったです。私は正常に働いている次のコードを行っているインターネットがONされている場合のみ
私が使用しているFirebaseDatabase.getInstance().setPersistenceEnabled(true);
データをオフラインで保存しても使用のためのmyRef.keepSynced(true);
同期を維持します。
ここでは、コードは次のようになります。
// COUNTER PART
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("counter");
myRef.keepSynced(true);
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Log.i("FB", "Snapshot: " + dataSnapshot);
long val = (long) dataSnapshot.getValue() + 1;
myRef.setValue(val);
mainBinding.contentLayout.textViewCounterVisits.setVisibility(View.VISIBLE);
mainBinding.contentLayout.textViewCounterVisits.setText(getString(R.string.total_visits, val));
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
Log.e("FB", "Error: " + error);
}
});
問題:
私は複数回のカウントオフライン用のアプリをオフラインで開くと。私はインターネットをオンにすると、それだけで更新されたデータとの同期だが、私は新しいカウントを追加することにより、更新カウントしたかったです。
例えば:
カウントは105です
アプリの1から10倍のためのオープニング(オフライン)
アプリの2から15倍のための開口部(オンライン)
今数は120です
アプリの1はオンラインになり、オープニングアプリと数が121を更新しています。
私たちはすべてを数える場合、それは131であるべきだと思います。
私たちはすべてを数える場合、それは131であるべきだと思います。
あなたはdescribdようメカニズムが本物であるならば、いや、それもないではありません121、それがあるべき116、あなたは、両方のアプリケーションで同じカウンタを使用しているので、それは、通常の動作です。ここではメカニズムは次のとおりです。
- カウントは105です
- アプリの1から10倍(オフライン)のためのオープニング- > Countはあるまだ 105
- >カウントは120(105 + 15) - でアプリ2 - (オンライン)15回用開口
アプリの1がオフラインになっているが、それは唯一の初期カウントの知識がある105およびそれらの10のキューイングされた増加の動作を制御します。アプリの1がオンラインになった時点で、それはとり115を、それが既存の上書きされます120その時点でデータベース内にある値を。だから今、データベース内のカウンターはの値がある115。アプリの1が再び開かれると、カウンタが増加することになる116。
アプリの1ので、オフライン、オンラインおよびその逆の間、アプリケーション2が何をしているのか分かりませんが、この「strage」動作が行われます。それは、マルチユーザー環境でカウンタをインクリメントすることになると一般的に言えば、それはあなたが先に行くべき道ではありません。次のポストから私の答えで説明したようなケースでは、一貫性のあるデータを持っている、あなたは、トランザクションを使用する必要があります。
しかしFirebase取引がオフラインで使用するためにサポートされていないことに注意してください。トランザクションは、キャッシュされたか、後で使用するために保存することはできません。トランザクションは絶対にトランザクション内のコードが正常に完了したことを確実にするために、サーバーとの往復の通信を必要とするからです。
だから私の意見では、あなたはそのインクリメントする必要がありcount
、ユーザーがオンラインで取引操作を使用している場合にのみ、フィールドを。
あなたが使用しようとする時にいくつかの点で考えるとPS クラウドFirestoreを、あなたは、名前の非常に便利なインクリメント操作方法は見つけることができます)FieldValue.incrementを(。