Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[🐛] Firestore Get query 4x slower on Android than iOS #4270

Closed
3 tasks done
BatRisbec opened this issue Sep 17, 2020 · 19 comments
Closed
3 tasks done

[🐛] Firestore Get query 4x slower on Android than iOS #4270

BatRisbec opened this issue Sep 17, 2020 · 19 comments
Labels
help: needs-triage Issue needs additional investigation/triaging. plugin: firestore Firebase Cloud Firestore type: bug New bug report

Comments

@BatRisbec
Copy link

Hi there,

We recently migrated from RNFirebase V5 to V6 and everything went well except for Firestore where we are experiencing some slow requests ONLY on Android (4x slower).

Test to reproduce :

Promise.all([ function1.get(), function2.get(), function3.get(), ]) .then(snaps => { console.log(snaps) })

Each function reads and gets ~80 documents. On iOS we get the log in about 2 seconds, when we need at least 8 seconds on Android (tested both in emulators and real devices).
The request reads and gets exactly the same documents.

We are using Firebase Android 25.5.0 & Firebase iOS 6.28.1. We used to have Firebase Android 25.7.0, but it was even slower than now...

Would you have any idea to explain such a huge difference ?

Thanks for your time !


Project Files

"@react-native-firebase/app": "^8.3.1",
"@react-native-firebase/firestore": "^7.5.3",

Have you converted to AndroidX? Yes

  • my application is an AndroidX application?
  • I am using android/gradle.settings jetifier=true for Android compatibility?
  • I am using the NPM package jetifier for react-native compatibility?

android/build.gradle:

        buildscript {
    ext {
        buildToolsVersion = "28.0.3"
        minSdkVersion = 16
        compileSdkVersion = 29
        targetSdkVersion = 29
        androidXCore = "1.0.2"
        androidXAnnotation = "1.1.0"
        androidXBrowser = "1.0.0"
    }
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath('com.android.tools.build:gradle:3.5.3')
        classpath 'com.google.gms:google-services:4.3.3'
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0'
    }
}

Environment

npmPackages:
react: ^16.8.6 => 16.9.0
react-native: 0.60.6 => 0.60.6
npmGlobalPackages:
react-native-cli: 2.0.1
react-native-git-upgrade: 0.2.7
react-native-rename: 2.2.2

- **Platform that you're experiencing the issue on**:
  - [ ] iOS
  - [X] Android
  - [ ] **iOS** but have not tested behavior on Android
  - [ ] **Android** but have not tested behavior on iOS
  - [ ] Both
- **`react-native-firebase V6

- **`Firebase Firestore
  - ``
- **Are you using `TypeScript`? N

@BatRisbec BatRisbec added help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report labels Sep 17, 2020
@mikehardy
Copy link
Collaborator

I think there's already an issue for this. Please note that "80 documents" means effectively nothing as "documents" can be wildly different. If you want to do valid benchmarks and discuss performance then actual data in use needs to be specified precisely and timed across versions for comparison.

To be completely clear: precise and accurate specification of exact data and versions is a strict requirement for performance discussion

The related work in the area is here
#4189
#3428

If I recall someone was trying to build a quick "data set generator" such that the data under test could be controlled, then tests could be run in a small test harness. That's the sort of thing needed in order to actually fix issues like this - reproducible test case, then comes the incremental improvement

@BatRisbec
Copy link
Author

Hello Mike,

Thanks for your answer! We were already following those two topics, however the solutions did not fix our issue.

To be more precise about our request in order to reproduce : each document is composed of 9 strings & 1 object of 30 elements.
However, the issue is not about the document itself, since we are making the same request on iOS and Android (on the exact same documents), with a time response way longer on Android (and it’s true about any of our Firestore queries actually, 4x times longer on Android).

We tried to downgrade to previous Firebase SDK versions (until the Firebase BoM 24.1.0 which was first used in RNFirebase V6), but it did not change anything to our issue.
We tried to go back to RNFirebase V5, and everything was as fast as it used to be, same speed on iOS and Android, so it really looks like an issue with V6 migration… Maybe we missed a step that could cause performance issue only on Android?

Thanks for your feedback!

@mikehardy
Copy link
Collaborator

I think that there is a performance issue between v5 and v6, I just think we don't have the rig set up to profile it and fix it - an app.js that could generate a set of data on demand that usefully showed the problem and exercised it with timing displayed. It's not the biggest hurdle to get over but it is the first step. Then it's a process of profiling + investigating the slow points + fixing + repeat

@BatRisbec
Copy link
Author

BatRisbec commented Sep 21, 2020

Hi Mike,

Thanks for your answer, as requested, we tested with a simple reproducible GET function on 300 identical documents on iOS and Android, here are the steps we followed:

  • Create a new react-native project
  • Install firebase app 7.8.2 & firestore module 8.4.3
  • Replace the App.js file by the one below
  • Add 300 documents to a new collection with the first button
  • Get 300 documents in a single request with the second button

App.js:

import React from "react"
import {
  View,
  Text,
  TouchableOpacity
} from 'react-native';

const testUser = require("./testUser.json");

import firestore from '@react-native-firebase/firestore'

const App = () => {
  return (
    <View style={{ justifyContent: "center", alignItems: "center" }}>
      <TouchableOpacity
        onPress={() => {
          for (i = 1; i <= 300; i++) {
            firestore().collection("testUsers").add({ ...testUser })
          }
        }}
      >
        <Text style={{ padding: 20 }}>Create profiles in firestore</Text>
      </TouchableOpacity>

      <TouchableOpacity
        onPress={() => {
          firestore().collection("testUsers").limit(300).get()
            .then(snap => {
              alert(snap._docs.length)
            })
        }}
      >
        <Text style={{ padding: 20 }}>Get profiles</Text>
      </TouchableOpacity>
    </View>
  );
};

export default App;

testUser.json:

{
    "gender": "male",
    "uid": "0000000000000000000",
    "birthday": "01/01/2000",
    "createdDays": 400,
    "geoLoc": {
        "_latitude": 48.6719974,
        "_longitude": 2.3488
    },
    "first_name": "John",
    "pic": "https://firebasestorage.googleapis.com/v0/b/que-du-sale.appspot.com/o/noPictureDeezer.jpg?alt=media&token=16e16dbc-ba97-40b5-8fa6-f7502085c46e",
    "geohash": "u09syh6qc",
    "premium": false,
    "lookingFor": "dates",
    "substyleDescArr": ["Metal", "Punk", "Rock", "Country", "Alternative", "Indie", "Blues", "Folk", "Funk", "Variété", "Hardcore", "Acid", "D'n'B", "Dubstep", "EDM", "Hardstyle", "House", "Techno", "Trance", "Rap", "Rnb", "Soul", "Classique", "Dub", "Ska", "Reggae", "Pop", "K-pop", "Jazz", "Latino", "World"
    ]
}

Here are our results:

Android : ~7000 ms on 1st launch, then ~5000 ms
iOS : ~2000ms on 1st launch, then ~1500 ms

I hope it will be easy enough for you to reproduce, and share with us any insights about our results (or yours if you get the same).

Thanks a lot for your time!

@mikehardy
Copy link
Collaborator

Fantastic! This should help a lot - let me collaborate with the Invertase folks to see what we can do with regard to a concerted performance tuning cycle. They're focus right now is substantially shifted to a separate work contract at the moment and I'm pretty busy myself but this has also been a long-standing issue and you've served it up nicely to reproduce!

Just in case you're hungry to go through it yourself and not wait (always the fastest way to get things done, FWIW) the next step is to get set up in Android Studio with profiling enabled and either use the IDE tools to profile (they are pretty good!) or set up code timers etc to effectively do the same, and start doing the typical performance tuning "test and take timings, make small change, repeat" loop

@mikehardy mikehardy added plugin: firestore Firebase Cloud Firestore Version: >= 6 Workflow: Needs Review Pending feedback or review from a maintainer. labels Sep 21, 2020
@BatRisbec
Copy link
Author

Thanks for your support and for bringing it to the team! Did you manage to reproduce it yourself, and, if so, did you notice a platform difference as we did?

I tried to use Android Studio Profiler to debug and analyze this request, however I am not used to it, so I am not really sure about what I should be looking for, any clue about this?

@mikehardy
Copy link
Collaborator

Invertase appears to be booked at the moment and I'm still booked myself as well unfortunately, I have not dropped it in my test harness yet to reproduce but having it as a self-contained App.js is beautiful so I'm reasonably sure I'll reproduce when I try.

My hunch (could be wrong!) is that something inefficient is being down with regards to data going back and forth across the react-native native/JS bridge, and it's CPU bound. Those are separate assertions and each bears examining, the yes/no test on whether they are correct will be found doing this: https://developer.android.com/studio/profile/cpu-profiler

@BatRisbec
Copy link
Author

Hi again,
Thanks for your feedback, we tried debugging it ourselves but we did not find anything conclusive...
We noticed that issues regarding Firestore performance were often raised in the Android Firebase SDK section, do you know when we could expect an update on the library, or have any news about this topic?
Also, we tried with the last Firestore module version, but our Android tests remains slow.
Thanks !

@mikehardy
Copy link
Collaborator

@BatRisbec thanks for the update. Sorry there was nothing conclusive, I guess I was hoping it was some obvious serialization issue on the JS/Native bridge, a shame nothing was obvious

There are no updates though, this is the issue tracking it here and you can see where we are (you are the only one testing right now, unfortunately) and unless you have a specific tracking issue in the firebase-android-sdk library with a clean reproduction from them based on their quickstarts, there is most likely nothing there. It's possible - if this is a problem reproducible on a firebase-android-sdk firestore quickstart project - to create an issue there though and see official attention from the firebase team

@lnminh58
Copy link

lnminh58 commented Oct 2, 2020

I'm facing with same issue.

@mikehardy
Copy link
Collaborator

@lnminh58 there was discussion that for some people, downgrading the android BOM (and thus firestore version) to lower versions - or perhaps moving forward to bom 25.11.0) had an effect. I recommend a quick (likely just 3 rebuilds) bisect of versions to see if that impacts your case.

@pehagg
Copy link
Contributor

pehagg commented Oct 6, 2020

As a side-note, FYI, we upgraded from @react-native-firebase/firestore 7.3.2 to 7.8.6 and Firestore's doc onSnapshot stopped working completely on Android. While investigating this, I bumped into firebase/firebase-android-sdk#1906 (comment), which could explain the issue being discussed here. I'll probably give upgrading the BOM a go, as we essentially can't use the current version of @react-native-firebase/firestore at all.

@BatRisbec
Copy link
Author

Hi @mikehardy, did you have by any chance the occasion to test our demo?

Thanks for your time!

@mikehardy
Copy link
Collaborator

Sorry I haven't had the time to test it @BatRisbec - I can say that I worked with @MujtabaFR to update the SDKs we rely on / use by default, and there is word that the new BoM (above 25.10.0 I think? we just bumped to 25.12.0) improves things. If you were not already overriding the BOM in your project, you might either try that or update to the new versions of react-native-firebase that are publishing as I type this and see if that helps you?

@BatRisbec
Copy link
Author

Wow amazing, we tested the latest combo App / Firestore / BoM versions, and it seems to work!
We are going to inject it in our project, and we'll let you know about the updates :)

Thanks a lot for having kept us updated on the topic!

@mikehardy
Copy link
Collaborator

Likewise thanks for letting me know your testing result to date - I wasn't sure how we were going to troubleshoot this coherently so I'm happy to hear a BoM upgrade could do it. I will preliminarily close this but as it does have a repro and other great info I'll stand by to reopen if there seems to be something going on in this module that the new BoM did not fix. Cheers @BatRisbec

@mikehardy mikehardy removed the Workflow: Needs Review Pending feedback or review from a maintainer. label Nov 26, 2020
@roger-ngx
Copy link

Wow amazing, we tested the latest combo App / Firestore / BoM versions, and it seems to work!
We are going to inject it in our project, and we'll let you know about the updates :)

Thanks a lot for having kept us updated on the topic!

how did you do ? can you share the result ?

@mikehardy
Copy link
Collaborator

@Thanh90 not sure on exactly what combination is now working (and what exactly "working" means for the original reporter) but the "BoM" is the android "bill of materials" - https://firebase.google.com/docs/android/learn-more#bom - and you may override it if you like, like so: https://rnfirebase.io/#android - however you may also see that we are well past the version mentioned here (25.something) by consulting our current BoM dependency:

"firebase": "28.2.1",

@roger-ngx
Copy link

roger-ngx commented Aug 11, 2021

@mikehardy I can confirm that there's no problem with v12.1.0. the slow caused by my processing after loading data from snapshot. loading data from snapshot is fast

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help: needs-triage Issue needs additional investigation/triaging. plugin: firestore Firebase Cloud Firestore type: bug New bug report
Projects
None yet
Development

No branches or pull requests

5 participants