Skip to content

[Firestore Performance Issue] Android query.get() takes over 20s while iOS completes under 1s for identical query #7198

@sana-20

Description

@sana-20

[READ] Step 1: Are you in the right place?

Issues filed here should be about bugs in the code in this repository.
If you have a general question, need help debugging, or fall into some
other category use one of these other channels:

  • For general technical questions, post a question on StackOverflow
    with the firebase tag.
  • For general Firebase discussion, use the firebase-talk
    google group.
  • For help troubleshooting your application that does not fall under one
    of the above categories, reach out to the personalized
    Firebase support channel.

[REQUIRED] Step 2: Describe your environment

  • Android Studio version: Android Studio Narwhal | 2025.1.1 Patch 1
  • Firebase Component: Firestore
  • Component version: Bom 34.0.0 (firestore 26.0.0)

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

On both Android and iOS, we fetch Firestore chat messages using the same query logic.
However, on Android, calling query.get() takes over 20 seconds, while on iOS it returns in under 1 second.

Here’s how the flow works on Android:

  1. We connect to Firestore using the given database ID.
  2. Then we call observeChat(), which attaches a snapshot listener to a collectionGroup("messages").
  3. Next, we call fetchUsersMeta() to get metadata for a user.
  4. Once that completes, we perform fetchMessages() in multiple chat rooms.

All Firestore indexes are properly set.
There are no other signs of network or device issues.
No Firebase exceptions or warnings are thrown.
The exact same document set is returned quickly on iOS but takes an abnormally long time on Android.

Example log output:

✅ Test 1: Parallel fetchMessages() calls

getUsersMeta duration: 147ms
fetchMessages - chatroom-id-1  → 21.20s, size=4
fetchMessages - chatroom-id-2  → 21.20s, size=24
fetchMessages - chatroom-id-3  → 21.22s, size=89
fetchMessages - chatroom-id-4  → 21.25s, size=638
fetchMessages - chatroom-id-5  → 21.46s, size=100
fetchMessages - chatroom-id-6  → 21.49s, size=77
fetchMessages - chatroom-id-7  → 21.51s, size=0 ⚠️
fetchMessages - chatroom-id-8  → 21.51s, size=6,790 ⚠️
fetchMessages - chatroom-id-9  → 22.99s, size=1,523
fetchMessages - chatroom-id-10 → 23.39s, size=4,308
fetchMessages - chatroom-id-11 → 24.46s, size=230
fetchMessages - chatroom-id-12 → 24.49s, size=2,181
fetchMessages - chatroom-id-13 → 24.96s, size=417
fetchMessages - chatroom-id-14 → 25.04s, size=57
fetchMessages - chatroom-id-15 → 25.04s, size=927
fetchMessages - chatroom-id-16 → 25.22s, size=120
fetchMessages - chatroom-id-17 → 25.26s, size=574
fetchMessages - chatroom-id-18 → 25.40s, size=691
fetchMessages - chatroom-id-19 → 25.51s, size=452
fetchMessages - chatroom-id-20 → 25.59s, size=76
fetchMessages - chatroom-id-21 → 25.61s, size=0 ⚠️
fetchMessages - chatroom-id-22 → 25.60s, size=468
fetchMessages - chatroom-id-23 → 25.69s, size=527
fetchMessages - chatroom-id-24 → 25.84s, size=618
fetchMessages - chatroom-id-25 → 25.96s, size=26
fetchMessages - chatroom-id-26 → 25.96s, size=58
fetchMessages - chatroom-id-27 → 25.97s, size=0 ⚠️
  • Total execution time exceeds 25 seconds, which is unexpectedly long for parallel processing.
  • Some requests with 0 results (e.g., chatroom-id-7, chatroom-id-21, chatroom-id-27) took over 21–25 seconds, indicating inefficient request execution or blocking behavior.
  • Fetching a large dataset (e.g., chatroom-id-8 with 6,790 messages) also took over 21 seconds, which is suspicious given its read-only nature and Firestore’s indexing performance.

✅ Test 2: Sequential fetchMessages() calls

getUsersMeta duration: 188ms

fetchMessages - chatroom-id-8  → 7.69s, size=6,790 ⚠️
fetchMessages - chatroom-id-14 → 109ms, size=57
fetchMessages - chatroom-id-9  → 1.41s, size=1,523
fetchMessages - chatroom-id-25 → 132ms, size=26
fetchMessages - chatroom-id-1  → 56ms, size=4
fetchMessages - chatroom-id-13 → 411ms, size=417
fetchMessages - chatroom-id-20 → 127ms, size=76
fetchMessages - chatroom-id-7  → 52ms, size=0
fetchMessages - chatroom-id-11 → 281ms, size=230
fetchMessages - chatroom-id-17 → 615ms, size=580
fetchMessages - chatroom-id-23 → 518ms, size=527
fetchMessages - chatroom-id-4  → 632ms, size=638
fetchMessages - chatroom-id-21 → 36ms, size=0
fetchMessages - chatroom-id-24 → 585ms, size=625
fetchMessages - chatroom-id-2  → 104ms, size=24
fetchMessages - chatroom-id-16 → 202ms, size=120
fetchMessages - chatroom-id-5  → 145ms, size=100
fetchMessages - chatroom-id-15 → 842ms, size=927
fetchMessages - chatroom-id-6  → 131ms, size=77
fetchMessages - chatroom-id-18 → 611ms, size=691
fetchMessages - chatroom-id-3  → 160ms, size=89
fetchMessages - chatroom-id-22 → 434ms, size=468
fetchMessages - chatroom-id-10 → 4.58s, size=4,308 ⚠️
fetchMessages - chatroom-id-19 → 472ms, size=452
fetchMessages - chatroom-id-26 → 137ms, size=58
fetchMessages - chatroom-id-27 → 33ms, size=0
fetchMessages - chatroom-id-12 → 2.07s, size=2,181 ⚠️
  • Sequential calls showed better performance than parallel, which is counterintuitive.
  • Large datasets like chatroom-id-8 (6,790 messages) took 7.69s, and chatroom-id-10 (4,308 messages) took 4.58s — performance scales linearly with message count.
  • iOS fetches the same 6,790 messages in under 1 second, highlighting abnormal slowness in Android Firestore.

✅ Test 3: Parallel fetchMessages() with All Results = 0

getUsersMeta duration: 3.370s

fetchMessages duration: 731.563ms, size=0
fetchMessages duration: 726.474ms, size=0
fetchMessages duration: 729.928ms, size=0
fetchMessages duration: 735.729ms, size=0
fetchMessages duration: 740.561ms, size=0
fetchMessages duration: 746.807ms, size=0
fetchMessages duration: 1.368s, size=0
fetchMessages duration: 1.365s, size=0
fetchMessages duration: 1.362s, size=0
fetchMessages duration: 1.364s, size=0
fetchMessages duration: 1.365s, size=0
fetchMessages duration: 1.372s, size=0
fetchMessages duration: 1.366s, size=0
fetchMessages duration: 1.368s, size=0
fetchMessages duration: 1.368s, size=0
fetchMessages duration: 1.371s, size=0
fetchMessages duration: 1.372s, size=0
fetchMessages duration: 1.372s, size=0
fetchMessages duration: 1.372s, size=0
fetchMessages duration: 1.374s, size=0
fetchMessages duration: 1.373s, size=0
fetchMessages duration: 1.373s, size=0
fetchMessages duration: 1.370s, size=0
fetchMessages duration: 1.355s, size=0
fetchMessages duration: 1.369s, size=0
fetchMessages duration: 1.363s, size=0
fetchMessages duration: 1.371s, size=0
  • Even though all results are empty (size=0), fetch durations range from 730ms to over 1.37s, which is inefficient.
  • Moreover, requests toward the end of the list consistently take longer than earlier ones — e.g., first fetch is ~730ms, but the last ones are ~1.37s.
  • Also, getUsersMeta() took 3.37s, which is unusually slow.

✅ Test 4: Sequential fetchMessages() with All Results = 0

getUsersMeta duration: 6.179s

fetchMessages duration: 397.815ms, size=0
fetchMessages duration: 46.808ms, size=0
fetchMessages duration: 130.414ms, size=0
fetchMessages duration: 39.804ms, size=0
fetchMessages duration: 46.340ms, size=0
fetchMessages duration: 73.890ms, size=0
fetchMessages duration: 48.975ms, size=0
fetchMessages duration: 38.574ms, size=0
fetchMessages duration: 66.986ms, size=0
fetchMessages duration: 77.339ms, size=0
fetchMessages duration: 68.151ms, size=0
fetchMessages duration: 79.475ms, size=0
fetchMessages duration: 45.685ms, size=0
fetchMessages duration: 91.039ms, size=0
fetchMessages duration: 41.715ms, size=0
fetchMessages duration: 46.727ms, size=0
fetchMessages duration: 66.391ms, size=0
fetchMessages duration: 100.449ms, size=0
fetchMessages duration: 43.368ms, size=0
fetchMessages duration: 92.011ms, size=0
fetchMessages duration: 47.804ms, size=0
fetchMessages duration: 74.602ms, size=0
fetchMessages duration: 288.936ms, size=0
fetchMessages duration: 62.520ms, size=0
fetchMessages duration: 56.893ms, size=0
fetchMessages duration: 58.928ms, size=0
fetchMessages duration: 166.459ms, size=0
  • Fetches are fast and mostly under 100ms, which is ideal for empty results.
  • However, getUsersMeta() took 6.18s, which is the slowest among all tests and lacks a clear reason.
  • In both Test 3 and 4, despite all fetch results being empty, getUsersMeta() becomes significantly slower — a behavior not observed in Test 1 and 2 —

Relevant Code:

fun connect() {
    firestore = Firebase.firestore(database = "$DB_CHAT$databaseId")
    observeChat()
} 

private fun observeChat() {
    val query = firestore.collectionGroup("messages")
        .whereGreaterThanOrEqualTo("updatedAt", Date().time)
        .where(Filter.inArray("roomIds", listOf("id1", "id2", "id3")))
        .where(
            Filter.or(
                Filter.equalTo("userId", "user-id-1"),
                Filter.inArray("userType", listOf("bot", "star"))
            )
        )
        .orderBy("updatedAt", Query.Direction.DESCENDING)

    query.addSnapshotListener { value, error ->
        // Snapshot updates handled here
    }
}

suspend fun fetchUsersMeta() {
    val query = firestore.collectionGroup("users")
        .whereEqualTo("userId", "user-id-1")

    val (snapshot, duration) = measureTimedValue { query.get().await() }
    println("getUsersMeta: $duration")
}

suspend fun fetchMessages() {
    val query = firestore.collection("chat/chatroom-id-1/messages")
        .where(
            Filter.or(
                Filter.equalTo("userId", "user-id-1"),
                Filter.inArray("userType", listOf("bot", "star"))
            )
        )
        .orderBy("createdAt", Query.Direction.DESCENDING)
        .whereGreaterThan("createdAt", Date().time - 24 * 60 * 60 * 1000)

    val (snapshot, duration) = measureTimedValue { query.get().await() }
    println("fetchMessages: $duration, size=${snapshot.documents.size}")
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions