Firebase Firestore addSnapshotListener(), возможно, вызывает ошибку «FragmentManager уже выполняет транзакции»

#android #firebase #google-cloud-firestore

#Android #firebase #google-облако-firestore

Вопрос:

Недавно я приступил к проекту, над которым некоторое время назад работал, с обновленными зависимостями. в связи с этим инцидентом я обновил функцию firestore dependency ( com.google.firebase:firebase-firestore ) с 17.1.5 до последней версии 18.2.0. Из-за этого обновления теперь мое приложение внезапно выдает следующую ошибку:

java.lang.Исключение IllegalStateException: FragmentManager уже выполняет транзакции

при вызове метода addSnapshotListener() фрагмента onActivityCreated . (поскольку ошибка примерно FragmentManager , я подумал, что это может быть актуально)

Вот конкретный код:

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

Когда я возвращаю зависимость обратно к старой, ошибка исчезает. Я предполагаю, что в Firestore произошло какое-то изменение в поведении, которое нарушило мой код, но я все еще не уверен, что именно это такое и как это исправить.

Вот подробная трассировка стека ошибок:

 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)
  

Обновление: только что обновлено до 19.0.0, и ошибка все еще существует.

Комментарии:

1. Пожалуйста, добавьте код, который вы используете, и укажите строку, в которой возникает эта ошибка.

2. Я не думал, что это будет необходимо, поскольку 1. существует только один addOnSnapshotLinstener метод, и реализация должна быть одинаковой для конкретной ссылки на документ и пути сбора. 2. мой код работает без каких-либо изменений, если я вернусь к старой версии зависимости Firestore. Тем не менее, я отредактировал вопрос, чтобы включить мой конкретный код, если это поможет.

3. Кто-нибудь хочет объяснить снижение?

4. В течение одного месяца мой проект был действительно хорош, я не обновлял его неделю, но теперь начала появляться эта ошибка. Я полагаю, что простое решение заключается в реализации eventListener

Ответ №1:

удалите getActivity() в вашем addSnapshotListener. Обработайте отключение прослушивателя с помощью listener.remove при onPause() .

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

// ...

// Stop listening to changes
registration.remove();
  

Комментарии:

1. Зачем мне это делать? Разве не стоит добавлять getActivity() слушателя, чтобы он знал о жизненном цикле действия?

2. Я просто попытался удалить параметр activity из прослушивателя, он сработал, но все равно будет служить обходным путем, поскольку теперь мне приходится вручную обрабатывать эти прослушиватели, соответствующие жизненному циклу моей активности. Знаете ли вы, почему это является причиной ошибки, и есть ли некомпромиссное исправление?

3. да, это была цель. Но я не знаю причины этого. Как только я обновился до новой версии, появляется эта ошибка. Возможно, это была ошибка.