React-native-firebase: platform/android: UI thread is blocking during the receiving of snapshot results

Created on 17 Jun 2018  路  17Comments  路  Source: invertase/react-native-firebase

Issue

The onSnapshot subscription queries are causing UI to freeze for 7-10 seconds when collections is having ~200 records in it.

The query performed in the JS code:

firebase
  .firestore()
  .collection('mycollection')
  .onSnapshot(this.handleCollectionUpdate)

It looks like that the problem is that the serialization of the QuerySnapshot is executed in the main thread which is performing slowly.

Added few more logging lines to describe the problem:

09:32:40.178 D/RNFirebaseAuth( 7470): RNFirebaseAuth:initialized
09:32:40.179 D/RNFirebasePerformance( 7470): New instance
09:32:47.001 D/RNFirebaseFirestore( 7470): collectionOnSnapshot: mqt_native_modules
09:32:47.012 D/RNFirebaseFirestore( 7470): collectionOnSnapshot after: mqt_native_modules
09:32:47.014 D/RNFirebaseFirestore( 7470): onSnapshot after: mqt_native_modules
09:32:48.048 D/RNFSCollectionReference( 7470): onSnapshot:onComplete:success main
09:32:48.048 D/RNFSCollectionReference( 7470): onSnapshot:creating map main
09:32:48.048 D/RNFSCollectionReference( 7470): onSnapshot:map created main
09:32:55.046 D/RNFSCollectionReference( 7470): onSnapshot:map serialized main
09:32:55.046 D/RNFSCollectionReference( 7470): onSnapshot:onComplete:sending event main
09:32:55.047 D/RNUtils ( 7470): onSnapshot:onComplete:send completed event main

e.g the execution time of 7 seconds in between 09:32:48.048 and 09:32:55.046 which is actually the call to FirestoreSerialize.snapshotToWritableMap(querySnapshot) in the handleQuerySnapshotEvent. The last text in the log is the name of the execution thread.

It looks like that QuerySnapshot is performing slow read operations when results and transformed which causes and the UI to block. Things are looking fine if this operation is performed in background thread.

Environment

Android

  1. Application Target Platform: Android
  2. Development Operating System: Android Studio
  3. Build Tools: 27.0.3
  4. React Native version: 0.55.4
  5. RNFirebase Version: 4.2.0
  6. Firebase Module:
    implementation "com.google.firebase:firebase-core:16.0.0"
    implementation "com.google.android.gms:play-services-base:15.0.1"

    implementation "com.google.firebase:firebase-auth:16.0.1"
    implementation "com.google.firebase:firebase-database:16.0.1"
    implementation "com.google.firebase:firebase-firestore:17.0.1"
    implementation "com.google.firebase:firebase-perf:16.0.0"

Bug Android Fixed Firestore Waiting for User Response

Most helpful comment

@chrisbianca did you managed to look into it ?

All 17 comments

@mgenov Thanks for flagging this, a very interesting spot. I'm curious - when you say that using a background thread doesn't cause such issues, do you have a code example of how you've tested this? We can use this as a basis for a fix if so.

Thanks for your feedback @chrisbianca. The code is really simple as it starts a new thread when the handleQuerySnapshotEvent is called:

Thread thread = new Thread(new Runnable() {
      @Override
      public void run() {
        WritableMap event = Arguments.createMap();
        WritableMap data = FirestoreSerialize.snapshotToWritableMap(querySnapshot);

        event.putString("appName", appName);
        event.putString("path", path);
        event.putString("listenerId", listenerId);
        event.putMap("querySnapshot", data);

        Utils.sendEvent(reactContext, "firestore_collection_sync_event", event);
      }
    });
thread.start();

It would be better query stuff to be executed in a background service or in an AsyncTask and the result of WritableMap or Some generic Data structure to be send to the UI thread after all transformations are completed.

@chrisbianca did you managed to look into it ?

Same issue here, but the Android app UI freeze when call firestore.set() method too.

@mgenov @joaom182 I'll push up something for this today/latest tomorrow to resolve this.

I did something similar recently for database() on this commit: https://github.com/invertase/react-native-firebase/commit/26338d8d6286bc83b597c6de2c25f6b904b68eec and the similar logic can be used here.

If you're interested; a before and after comparison of the UI for the db change can be seen here.


Loving react-native-firebase and the support we provide? Please consider supporting us with any of the below:

@Salakar Thanks! This fixes will be a PR?

@joaom182 it will be yes - will tag you in it when it lands.

@Salakar any progress?

@joaom182 @mgenov @lucasgray @diehardest

This has been pushed up; please could you try out this branch:

https://github.com/invertase/react-native-firebase/tree/firestore-android-asynctask

A couple of people on discord have tested already;
image

Let me know how you get on, thanks.


Loving react-native-firebase and the support we provide? Please consider supporting us with any of the below:

@Salakar this fix is available on v4.3.8 or only in v5.0.0?

I still seem to experience this bug with v5.2.0...

I may be encountering this issue on v5.3.1. I'm experiencing very poor performance on android with UI freezing for seconds at a time. I'll add more detail here when I'm able to find some.

Facing firestore query freeze issue on v5.5.4

This issue has been closed for almost a year and a half - open a new issue with full details, but please update to current versions first (v5.6.0 for react-native-firebase and current SDKs for firebase) or the troubleshooting time will likely be wasted as firebase sdks move quickly, usually with bugfixes...

Hi, I still have this issue in the latest version (6.2.0).

this.ref .where('members', 'array-contains', uid) .onSnapshot(list => this.onSnapshot(list));

@lironsher latest is 6.3.4

does it solve the issue?

Was this page helpful?
0 / 5 - 0 ratings