良い質問。したがって、注意すべき点がいくつかあります。
リスナーをどこに接続していますか?これを 以外の場所にアタッチすると、onResume
リスナーが再初期化されます。リスナーを設定すると、その特定のノードのすべてのイベントが発生します。ただし、Firebase 参照への登録と登録解除はすべてonPause
.onResume
任意の Firebase リスナーのインスタンスを複数持つことができます。
firebase は、この特定のリスナーが既に存在することを知るほどスマートですか?
Firebaseはリスナーが既に存在することを認識しており、同じイベントを 2 回送信することはありません。ただし、回転すると、リスナーの新しいインスタンスが作成されます。Firebase は、これを同じインスタンス化されたリスナーとして認識できません。したがって、すべてのデータを再度受信します。
Firebase はすべてのデータをキャッシュします。フラグメントがアタッチされ、リスナーが設定されると、firebase は 2 つの主要な呼び出しを行います。
キャッシュを最初に呼び出すのは、ネットワークが遅い場合やネットワークがない場合でも機能するため、便利です。さて、ここで我慢してください... Firebase がオンライン サーバーからそのスナップショットを受信すると、リモート オブジェクトとローカル オブジェクトの複雑な評価が行われます。Firebase は、その能力を最大限に発揮するために、タイムスタンプとブラック マジックを利用する複雑な ID を使用してオブジェクトをマージします [ソースが必要です]。この新しいスナップショットを使用すると、必要に応じてサーバーに保存されます。次に、**Firebase は、キャッシュされたバージョンと異なり、そのデータを提供したリスナーのインスタンスに関連して変更された場合にのみ、日付を提供します。このキャッシュ駆動型の構造は、データを保存するときにも適用されます。
まず、キャッシュに保存します。
2 番目のトリガー コールバック。
3 回目 - サーバーへの保存を試みます。
質問に答えるには
リスナーを Firebase onPause
/onResume
にアタッチすると、すべてのデータが再び受信されます。再度受信しないようにする唯一の方法は、そのリスナーの同じインスタンスを維持することです。
リスナー インスタンスを維持することに加えて、別のソリューションも使用しました。私の意見では、私はそれが好きではありません。しかし、それでも私が最も頻繁に使用するものです。私がすることは、
final List<String>
と呼ばれるを保持しignoredList
ます。このリストはString
、アダプターに既にあるオブジェクトのキーであるキーで構築されます。
次に、onPause
このデータを my に追加し、リスナーignoredList
を null にします。childEvent
コールバックの後、リスナーonResume
の新しいインスタンスを設定します。childEvent
イベントリスナーで、onAdded
新しく追加されたオブジェクトをリストと照合します。持っている場合は、リストから削除しますが、それ以外は何もしません。本質的にそれを無視します。オブジェクトが私の中にない場合は、ignoredList
通常どおり処理します。以外のコールバックonAdded
(onRemoved
onChanged
またはonMoved
) のいずれかからそれを受け取った場合、そのイベントをリスト内のそのオブジェクトに変更し、から削除しignoredList
ます。
さて、これが実際には最善の解決策ではないことは認めます。2 つのソースが同じ DataSnapshot を変更している場合、誤ったデータが表示される可能性があります。それは小さなチャンスですが、完全に可能です。幸いなことに、データ セットが不正確な場合は、Firebase に保存されません。
私は常にこのためのより良い戦略を積極的に探しており、見つけた場合は共有します. その間、このソリューションは私のアプリで完全に機能しています。