Firebase Firestore addSnapshotListener() possibly causing "FragmentManager is already executing transactions" error

jac*_*314 3 android firebase google-cloud-firestore

I recently picked up on a project that I was working on a while back with updated dependencies, relating to this incident, I updated firestore's dependency (com.google.firebase:firebase-firestore) from 17.1.5 to the latest 18.2.0. Because of this update, now my app is suddenly throwing the following error:

java.lang.IllegalStateException: FragmentManager is already executing transactions

at a call of addSnapshotListener() in a Fragment's onActivityCreated method. (since the error is about FragmentManager, I thought this might be relevant)

Here's the specific code:

docRef.collection(COLLECTION_PATH).addSnapshotListener(Objects.requireNonNull(getActivity()), (queryDocumentSnapshots, e) -> {
      //other stuff to do after detecting collection change
});
Run Code Online (Sandbox Code Playgroud)

When I revert the dependency back to the old one, the error disappears. I'm guessing there's some sort of behavioral change in Firestore that broke my code, but I'm still not sure what exactly it is and how to fix it.

Here's the detail error stack trace:

java.lang.IllegalStateException: FragmentManager is already executing transactions
        at androidx.fragment.app.FragmentManagerImpl.ensureExecReady(FragmentManagerImpl.java:1657)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1717)
        at androidx.fragment.app.FragmentManagerImpl.executePendingTransactions(FragmentManagerImpl.java:228)
        at com.google.firebase.firestore.util.ListenerRegistrationImpl.lambda$onFragmentActivityStopCallOnce$1(com.google.firebase:firebase-firestore@@18.2.0:190)
        at com.google.firebase.firestore.util.ListenerRegistrationImpl$$Lambda$2.run(Unknown Source:4)
        at android.app.Activity.runOnUiThread(Activity.java:6282)
        at com.google.firebase.firestore.util.ListenerRegistrationImpl.onFragmentActivityStopCallOnce(com.google.firebase:firebase-firestore@@18.2.0:174)
        at com.google.firebase.firestore.util.ListenerRegistrationImpl.<init>(com.google.firebase:firebase-firestore@@18.2.0:209)
        at com.google.firebase.firestore.Query.addSnapshotListenerInternal(com.google.firebase:firebase-firestore@@18.2.0:917)
        at com.google.firebase.firestore.Query.addSnapshotListener(com.google.firebase:firebase-firestore@@18.2.0:882)
        at com.google.firebase.firestore.Query.addSnapshotListener(com.google.firebase:firebase-firestore@@18.2.0:823)
        ... [My app's call to addSnapshotListener] ...
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2565)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:907)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1235)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1301)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:710)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2071)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1861)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1816)
        at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManagerImpl.java:1693)
        at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:560)
        at androidx.fragment.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:148)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1092)
        at androidx.viewpager.widget.ViewPager.onMeasure(ViewPager.java:1622)
        at android.view.View.measure(View.java:23169)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:743)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:815)
        at android.view.View.measure(View.java:23169)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
        at android.view.View.measure(View.java:23169)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:403)
        at android.view.View.measure(View.java:23169)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
        at android.view.View.measure(View.java:23169)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
Run Code Online (Sandbox Code Playgroud)

Update: just updated to 19.0.0 and the error still exists.

Aza*_*mov 6

在 addSnapshotListener 中删除 getActivity()。使用 onPause() 上的 listener.remove 处理侦听器分离。

    Query query = db.collection("cities");
ListenerRegistration registration = query.addSnapshotListener(
        new EventListener<QuerySnapshot>() {
            // ...
        });

// ...

// Stop listening to changes
registration.remove();
Run Code Online (Sandbox Code Playgroud)