


Firestore など Firebase のプロダクトは、オンラインで使用するのが基本的な使い方だとは思いますが、オフラインの時のための機能というのも用意されています。
Firestore でのオフライン対応について書かれた公式ドキュメントに、以下のようなコードが載っています。
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setPersistenceEnabled(true)
.build();
firestore.setFirestoreSettings(settings);
setPersistenceEnabled メソッドに true を渡すことで、キャッシュが有効になります。
オフラインの時、キャッシュが有効の場合、Firestore ドキュメントからデータを取得すると、onComplete コールバックが発生し、処理は成功となり、キャッシュデータが取得されます。
ただし、キャッシュが存在しない場合は、task.isSuccessful() が false となります。
オフラインの時、キャッシュが無効の場合、onComplete コールバックが発生し、task.isSuccessful() が false となります。
以下のようにして、get メソッドに Source 列挙型の値を渡すことで、サーバ/キャッシュから値を取得することを明示的に指定できます。
DocumentReference doc = firestore.collection("Hoge").document("Fuga");
doc.get(Source.CACHE).addOnCompleteListener(this, new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Success");
} else {
Log.d(TAG, "Failure");
}
}
});
Source.CACHE を渡すことで、常にキャッシュから取得するようになります。
Source.SERVER を渡した場合は、常にサーバから取得を試みるようになります。
Source.DEFAULT はデフォルトの挙動になります。
次に、Firestore ドキュメントへのデータ格納時の挙動について見てみます。
コードは以下のような感じになるかと思います。
DocumentReference doc = firestore.collection("Hoge").document("Fuga");
doc.set(data).addOnCompleteListener(this, new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Success");
} else {
Log.d(TAG, "Failure");
}
}
});
オフライン時に、このコードを実行すると、onComplete コールバックは発生しません。
オフラインの間、このオペレーションは維持されており、オンラインに復帰した際にデータベースに対する書き込みが行われて、onComplete コールバックが発生します。
筆者が実験した限りでは、オフラインの間にアプリを終了した場合、再度アプリを立ち上げても、データベースへの書き込みは行われないようでした。
また、このオペレーションをキャンセルしたい場合 (onComplete を強制的に起こさせたい) ですが、その方法について見つけることができませんでした。
ですので、onComplete が発生しない限りアプリの進行が止まってしまう、というような作りにはしてはいけない、ということになるかと思います。