Firestore: pending writes silently lost when issued around disableNetwork() / enableNetwork()
メンテナーはふだん 1 日以内に返信
@cherylEnkidu がすでに取り組んでいます。
2026年7月22日 から。
評価
この issue はまだ評価されていません。
説明
[REQUIRED] Step 1: Describe your environment
- Android Studio version: any (reproduced on emulator and physical device)
- Firebase Component: Firestore
- Component version: reproduced with
firebase-bom:33.1.1(firebase-firestore); originally observed June 2024, still relevant as of the FlutterFire triage in July 2026
[REQUIRED] Step 2: Describe the problem
Steps to reproduce:
When a write (e.g. update() with FieldValue.increment()) is issued while the network is being toggled via disableNetwork() / enableNetwork(), the write can be silently dropped — it never reaches the backend and no error is surfaced. Starting from a field value of 0, calling increment(-1) followed by increment(+1) across a network toggle can leave the server value at -1 (or lower after repeated runs) instead of 0.
This was originally reported against FlutterFire in firebase/flutterfire#12952 with a Flutter reproduction (roughly 40–50% hit rate per attempt, near-certain when repeated). A FlutterFire maintainer then reproduced it in a pure native Android project using this SDK directly, with no Flutter involved: TarekkMA/firebase-android-reproduction @ ff-issue/12952. On that basis the FlutterFire issue was closed as an upstream native SDK bug (comment) — FlutterFire only forwards increment/disableNetwork/enableNetwork to this SDK. I'm filing this issue here to continue the investigation, as no upstream issue existed yet.
Trigger sequence (from the original report, translated to the Android SDK):
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference doc = db.collection("test").document("doc"); // field "v" starts at 0
Map<String, Object> minusOne = new HashMap<>();
minusOne.put("v", FieldValue.increment(-1));
Map<String, Object> plusOne = new HashMap<>();
plusOne.put("v", FieldValue.increment(1));
doc.update(minusOne); // not awaited, as in real offline-capable apps
db.disableNetwork();
doc.update(plusOne);
db.enableNetwork();
Repeat the sequence a few times (a 2–3 second pause between runs is enough; firing many sequences concurrently makes it near-deterministic) and watch the document via a snapshot listener or the console.
The disableNetwork()/enableNetwork() calls are only a deterministic stand-in for an unstable real-world connection — the original report reproduced the same loss on a physical device with a genuinely flaky network, it is just far more cumbersome to trigger that way.
Expected result
Both queued writes are eventually delivered once the network is re-enabled — offline mutations are documented as queued and synced when connectivity returns. The field ends at 0 after every -1/+1 pair, every time.
Actual result
Intermittently (~40–50% of attempts in the Flutter harness, also confirmed in the native Android repro linked above) one of the writes is lost: the field ends at -1, and repeated runs drift further negative. The lost write's task never fails — there is no error signal that the mutation was dropped, so the client and server silently diverge.
Relevant Code:
- Native Android reproduction (by FlutterFire maintainer @TarekkMA): https://github.com/TarekkMA/firebase-android-reproduction/tree/ff-issue/12952
- Original Flutter reproduction with full source and screen recording: https://github.com/firebase/flutterfire/issues/12952
Note: the same behavior was also reproduced on iOS through FlutterFire, so the defect is likely shared across the native SDKs' offline mutation queue logic rather than being Android-specific.
- 主要言語
- Java
- スター
- 2.6k
- フォーク
- 733
- 平均マージ
- 2日 15時間
- マージ済み PR(30日)
- 72
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
firebase/firebase-android-sdk のほかの issue
-
api: remoteconfig
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
firebase/firebase-android-sdk#8827 ·
メンテナーはふだん 1 日以内に返信
-
Crashlytics plugin writes build ID lists in directory listing order, so APKs can differ between machines対応中かも @mrober が 8 日前に担当しました。 オープンapi: crashlytics
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
firebase/firebase-android-sdk#8789 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
api: auth
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
firebase/firebase-android-sdk#8505 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 15/100
firebase/firebase-android-sdk#8835 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 25/100
firebase/firebase-android-sdk#8832 ·
メンテナーはふだん 1 日以内に返信
firebase/firebase-android-sdk の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
メンテナーはふだん 1 日以内に返信
-
RIS export splits an organization name containing “and” into multiple authors対応中かも @Gautam-aman が今日担当しました。 オープンstatus: needs-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
JabRef/jabref#17821 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
FailureContext.java rounds down thresholds in lastedAtLeast()対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 86/100
メンテナーはふだん 1 日以内に返信