Skip to content

Firestore cache index misses pending writes after a relaunch #16742

Description

@natep

Description

Full disclosure: I used a coding agent to diagnose this issue and create a minimal reproducer. But it seems plausible. We are seeing this issue occur during beta testing of a new Firestore-backed feature in our iOS app.


With the persistent cache and enableIndexAutoCreation(), a getDocuments(source: .cache) that an auto-created cache index serves misses a document whose write is still pending, once the client has been restarted. A cache snapshot listener on the same query delivers the document. The cache read sees it again as soon as the write is acknowledged.

Reproduced with firebase-ios-sdk 12.19.2 (also 12.15.0) against the Firestore emulator on the iOS 26.5 simulator.

Reproducing the issue

I have attached an Xcode project containing a minimal reproduction.

FirestoreIndexRepro.zip

Running it

  1. In this folder: firebase emulators:start --only firestore --project demo-index-repro (port 8080, rules open; see firebase.json).
  2. Run the FirestoreIndexReproTests tests in Xcode.

See the included README.md for more details.

Firebase SDK Version

12.19.2

Xcode Version

26.6

Installation Method

Swift Package Manager

Firebase Product(s)

Firestore

Targeted Platforms

iOS

Relevant Log Output

If using Swift Package Manager, the project's Package.resolved

Expand Package.resolved snippet
{
  "originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329",
  "pins" : [
    {
      "identity" : "abseil-cpp-binary",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/abseil-cpp-binary.git",
      "state" : {
        "revision" : "bbe8b69694d7873315fd3a4ad41efe043e1c07c5",
        "version" : "1.2024072200.0"
      }
    },
    {
      "identity" : "app-check",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/app-check.git",
      "state" : {
        "revision" : "97f7d74dd0e8f3d0fe5fc75cc8957aa73bdc948a",
        "version" : "11.3.2"
      }
    },
    {
      "identity" : "firebase-ios-sdk",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/firebase-ios-sdk",
      "state" : {
        "revision" : "8c29ca981990a32e626c8617544fa65d22b1834f",
        "version" : "12.19.2"
      }
    },
    {
      "identity" : "google-ads-on-device-conversion-ios-sdk",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/googleads/google-ads-on-device-conversion-ios-sdk",
      "state" : {
        "revision" : "0208e2681ec81f8a9c81084696f60fcce26cb7ee",
        "version" : "3.7.0"
      }
    },
    {
      "identity" : "googleappmeasurement",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleAppMeasurement.git",
      "state" : {
        "revision" : "b8455dd2ff55cc269fda7a4f9eac6c1e3588c53f",
        "version" : "12.19.2"
      }
    },
    {
      "identity" : "googledatatransport",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleDataTransport.git",
      "state" : {
        "revision" : "ba3358d3c3dbae8ef230b58a46b97ad65e84e974",
        "version" : "10.1.1"
      }
    },
    {
      "identity" : "googleutilities",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleUtilities.git",
      "state" : {
        "revision" : "92c8f6dc3ac375d6febdfcb3db68bc3d10633db3",
        "version" : "8.1.3"
      }
    },
    {
      "identity" : "grpc-binary",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/grpc-binary.git",
      "state" : {
        "revision" : "75b31c842f664a0f46a2e590a570e370249fd8f6",
        "version" : "1.69.1"
      }
    },
    {
      "identity" : "gtm-session-fetcher",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/gtm-session-fetcher.git",
      "state" : {
        "revision" : "724a52eea6329b7e12d3ad8300d76ca9f3895fcc",
        "version" : "5.3.1"
      }
    },
    {
      "identity" : "interop-ios-for-google-sdks",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/interop-ios-for-google-sdks.git",
      "state" : {
        "revision" : "040d087ac2267d2ddd4cca36c757d1c6a05fdbfe",
        "version" : "101.0.0"
      }
    },
    {
      "identity" : "leveldb",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/leveldb.git",
      "state" : {
        "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1",
        "version" : "1.22.5"
      }
    },
    {
      "identity" : "nanopb",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/nanopb.git",
      "state" : {
        "revision" : "3851d94a41890dea16dc3db34caf60e585cb4163",
        "version" : "2.30910.1"
      }
    },
    {
      "identity" : "promises",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/promises.git",
      "state" : {
        "revision" : "f4a19a3c313dc2616c70bb49d29a799fb16be837",
        "version" : "2.4.1"
      }
    }
  ],
  "version" : 3
}

If using CocoaPods, the project's Podfile.lock

Expand Podfile.lock snippet
Replace this line with the contents of your Podfile.lock!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions