Firestore не может получить данные после повторного подключения к Интернету

Я использую Firestore с Android SDK (11.6.2), и у меня возникает исключение, когда мое устройство было отключено и повторно подключается к Интернету.

При запросе документа firestore завершается ошибкой со следующим исключением задачи:

com.google.firebase.firestore.FirebaseFirestoreException: не удалось получить документ, поскольку клиент отключен.

Однако устройство подключено, я могу делать сетевые запросы помимо использования Firestore, и они преуспевают. Эта ошибка непоследовательна, иногда запрос выполняется сразу после повторного подключения к Интернету. Иногда запрос снова и снова терпит неудачу, затем выполняется успешно, иногда более чем через минуту после повторного подключения устройства к Интернету.

Вот пример запроса, который вызывает исключение:

val docRef = firestore.collection("foo").document("bar")
docRef.get().addOnCompleteListener { task ->
    if (task.isSuccessful) {
        Log.d("FirestoreSourceSet", "Get document success")
    } else {
        Log.e("FirestoreSourceSet", "Get document error", task.exception)
    }
}

Я не использую автономные возможности Firestore, поэтому экземпляр FirebaseFirestore инициализируется в первый раз с флагом setPersistenceEnabled(false):

val firestoreSettings = FirebaseFirestoreSettings.Builder()
    .setPersistenceEnabled(false)
    .build()

val firestore = FirebaseFirestore.getInstance().apply {
    this.firestoreSettings = firestoreSettings
}

Почему Firestore возвращает эту ошибку, даже если устройство подключено к сети? Мне что-то не хватает в конфигурации Firestore, чтобы избежать этой ошибки?

Я попытался обновить Firebase до версии 11.8.0, но столкнулся с тем же поведением.

Журналы

Это журналы при попытке получить синхронизацию некоторых данных с Firestore (которая начинается с получения документа) после выхода из режима полета: https://pastebin.com/xDMG2Pzj

Сеть уже доступна до первого вызова Firestore, так как я ждал, пока Wi-Fi установится, и проверил его с помощью ConnectivityManager Android, прежде чем продолжить работу с Firestore.

Множественные вызовы вызваны тем, что я вручную повторяю попытку с помощью кнопки каждый раз, когда получаю сообщение об ошибке, до тех пор, пока документ не будет успешно получен.

Первая строка журнала - это когда я включаю авиарежим, который закрывает поток Firestore.

Изменить: проблема

Firebase не имеет общедоступного трекера, но я сообщил о проблеме с помощью их инструмента отчетов, и создал репо, в котором воспроизводится проблема.

Они признали проблему, но не смогли предоставить расчетное время прибытия, поэтому нам нужно подождать:

Если мы выпустим исправление, мы объявим об этом на нашей странице примечаний к выпуску.

Это все еще проблема с firestore-core 17.0.4.


person Matthieu Esnault    schedule 10.01.2018    source источник
comment
Есть ли значительная задержка между вызовом get() и выводом сообщения об ошибке? По моему опыту, Firestore пытается подключиться примерно в течение 30 секунд, поэтому знание задержки помогает определить, на какой фазе он находится. Я также рекомендовал бы включение ведения журнала отладки, чтобы увидеть, дает ли трафик в сети подсказку о том, почему клиент может ' т подключиться.   -  person Frank van Puffelen    schedule 10.01.2018
comment
В большинстве случаев задержка между вызовом и ошибкой составляет от 4 до 5 секунд. Иногда это меньше секунды, иногда до 10 секунд. Я включил ведение журнала и обновил им свой пост.   -  person Matthieu Esnault    schedule 07.02.2018
comment
У меня тоже есть эта проблема на Android, хотя я использую постоянство в автономном режиме. Есть ли в этом прогресс?   -  person Arctic45    schedule 12.04.2018
comment
Та же проблема. Есть новости с их стороны?   -  person Sirelon    schedule 29.05.2018
comment
Столкнувшись с той же проблемой. Любые обновления?   -  person Swapnil    schedule 02.09.2018
comment
К сожалению, у меня нет обновлений по этому поводу. Об исправлении будет объявлено в примечаниях к выпуску, когда оно станет доступным, но у нас нет ETA. Проблема все еще присутствует при использовании firestore-core 17.0.4   -  person Matthieu Esnault    schedule 03.09.2018
comment
Все еще испытываю это с Firestore 17.1.5.   -  person Sven Jacobs    schedule 22.01.2019
comment
А с 19.0.0.   -  person FractalBob    schedule 09.09.2019
comment
Испытываете ту же проблему в марте 2020 года ... Есть обновления?   -  person Richard Suarez    schedule 16.03.2020
comment
Тот же выпуск в декабре 2020 г.   -  person Florian Walther    schedule 24.12.2020
comment
И снова сегодня с 22.0.1. Я не могу продолжать разработку с этим шоу-стопором. Кто-нибудь слушает ??   -  person FractalBob    schedule 08.01.2021
comment
Все еще происходит с Firestore 22.1.2. Это очень расстраивает :(   -  person Sven Jacobs    schedule 15.04.2021


Ответы (5)


Из официальной документации:

Чтобы использовать сохранение в автономном режиме, вам не нужно вносить какие-либо изменения в код, который вы используете для доступа к данным Cloud Firestore. При включенном автономном постоянстве клиентская библиотека Cloud Firestore автоматически управляет доступом к данным в режиме онлайн и в автономном режиме и синхронизирует локальные данные, когда устройство снова в сети.

При инициализации Cloud Firestore вы можете включить или отключить сохранение в автономном режиме. Итак, при использовании следующей строки кода:

val firestoreSettings = FirebaseFirestoreSettings.Builder()
    .setPersistenceEnabled(false)
    .build()

Фактически вы устанавливаете постоянство на false, вы отключаете эту функцию. Чтобы решить эту проблему, просто удалите эту строку кода. По умолчанию Firestore имеет .setPersistenceEnabled(true).

person Alex Mamo    schedule 10.01.2018
comment
Я не хочу использовать постоянство Firestore, так как я уже использую локальную базу данных для хранения данных, поэтому явное отключение. Я нормально получаю сообщение об ошибке, когда устройство находится в автономном режиме, если я пытаюсь получить данные из Firestore. Моя проблема заключается в том, чтобы получить эту Failed to get document because the client is offline ошибку, когда устройство подключено к сети после повторного подключения к Интернету. - person Matthieu Esnault; 10.01.2018
comment
Зачем использовать другую базу данных для хранения данных, если Cloud Firestore предоставляет то же самое, но ничего не делает? Вам даже не нужно это указывать, Firestore по умолчанию имеет .setPersistenceEnabled (true). Итак, когда я прочитал здесь и здесь, это может быть проблема, которая скоро будет решена. Помните, Cloud Firestore все еще находится в стадии бета-версии. - person Alex Mamo; 10.01.2018
comment
Спасибо, что указали на этот пост, я сделал не нашел но это та же проблема. Я понимаю, что Cloud Firestore все еще находится в стадии бета-тестирования, но я хотел знать, было ли это чем-то с нашей стороны. Я нашел эту страницу, чтобы сообщить о проблемах, но не могу найти проблему трекер, чтобы я мог отслеживать эту проблему, если она уже известна. - person Matthieu Esnault; 07.02.2018
comment
Вы пытались включить ведение журнала отладки?? Вы видели что-то странное? - person Alex Mamo; 07.02.2018
comment
Я включил ведение журнала отладки и обновил свой пост, чтобы включить его в него. Firestore не удается повторно разрешить хост firestore.googleapis.com, увеличивая задержку до тех пор, пока ему не удастся установить соединение. - person Matthieu Esnault; 07.02.2018
comment
Я рекомендую вам задать еще один вопрос и добавить все эти журналы, и, возможно, один из членов команды Firebase ответит на него. Или отправьте этот вопрос в службу поддержки Firebase. Держите меня также в курсе. - person Alex Mamo; 07.02.2018
comment
Фактически проблема до сих пор не решена. Он появляется в Firestore 22.0.1. - person FractalBob; 08.01.2021

Эта проблема была устранена в выпуске 17.1.5 Cloud Firestore.

См. Официальный журнал изменений https://firebase.google.com/support/release-notes/android

Cloud Firestore теперь быстрее восстанавливается после плохого состояния сети.


При использовании моего проекта воспроизведения с версией 18.0.0 проблемы действительно нет.

person Matthieu Esnault    schedule 04.02.2019
comment
Версия 20.1.0 и поведение точно такое же, как описано в вопросе. Я не думаю, что это вообще исправлено. - person Pierre-Olivier Dybman; 23.07.2019
comment
Я использую firestore sdk 19.0.0 для Android, и у меня все еще есть эта проблема, когда я пытался получить документ по идентификатору, которого не существует - person gbixahue; 20.10.2019
comment
А у меня до сих пор проблема с 21.7.1 - person FractalBob; 18.10.2020
comment
@gbixahue Точно такая же проблема для меня. Это работает, если я не пытаюсь получить документ по несуществующему идентификатору. - person Florian Walther; 24.12.2020

Я сталкиваюсь с той же проблемой с 2018 года и пока не нашел подходящего решения. Это все еще происходит с версией 22.1.2 библиотеки Firestore для Android. Как прокомментировано в исходный код DocumentReference, это исключение выдается, когда клиент находится в автономном режиме и запрошенный документ недоступен в локальном кэше. Также есть недавнее объяснение этого поведения, написанное Денвер Конибер.

Это исключение может возникнуть для DocumentReference.get() вызовов. Вот пример трассировки стека:

com.google.firebase.firestore.FirebaseFirestoreException: Failed to get document because the client is offline.
       at com.google.firebase.firestore.DocumentReference.lambda$getViaSnapshotListener$1(DocumentReference.java:331)
       at com.google.firebase.firestore.DocumentReference$$Lambda$2.onEvent(DocumentReference.java:8)
       at com.google.firebase.firestore.DocumentReference.lambda$addSnapshotListenerInternal$2(DocumentReference.java:504)
       at com.google.firebase.firestore.DocumentReference$$Lambda$3.onEvent(DocumentReference.java:16)
       at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42)
       at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(AsyncEventListener.java:2)
       at com.google.firebase.firestore.util.Executors$$Lambda$1.execute(Executors.java)
       at com.google.firebase.firestore.core.AsyncEventListener.onEvent(AsyncEventListener.java:39)
       at com.google.firebase.firestore.core.QueryListener.raiseInitialEvent(QueryListener.java:176)
       at com.google.firebase.firestore.core.QueryListener.onViewSnapshot(QueryListener.java:95)
       at com.google.firebase.firestore.core.EventManager.addQueryListener(EventManager.java:97)
       at com.google.firebase.firestore.core.FirestoreClient.lambda$listen$6(FirestoreClient.java:160)
       at com.google.firebase.firestore.core.FirestoreClient$$Lambda$6.run(FirestoreClient.java:12)
       at com.google.firebase.firestore.util.AsyncQueue.lambda$enqueue$2(AsyncQueue.java:436)
       at com.google.firebase.firestore.util.AsyncQueue$$Lambda$2.call(AsyncQueue.java:1)
       at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor.lambda$executeAndReportResult$1(AsyncQueue.java:322)
       at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$$Lambda$2.run(AsyncQueue.java:1)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
       at java.util.concurrent.FutureTask.run(FutureTask.java:266)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
       at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:229)
       at java.lang.Thread.run(Thread.java:919)

Прошу прощения, если этот ответ не решит проблему, но эта информация была бы слишком длинной для комментария к исходному сообщению.

person Sven Jacobs    schedule 16.04.2021

У меня тоже такая же проблема. Есть обходной путь - приложение ждет некоторое время и делает еще одну попытку получить данные с сервера.

Вот макет (это Flutter / dart):

   List<Course> items;

   Widget build(BuildContext context) {
    ...
    loadData();
    ...
    //building th UI with data from items list
    ...
   }


    loadData() async {        
        //is not loaded but there is internet connection
        if (!isLoaded&&isConnected) {
          try {
              querySnapshot = await query.getDocuments(source: Source.server);
            } 
            catch (ex) {
              print(ex);
              Future.delayed(Duration(seconds: 10), () {
              // setState to trigger build 10 seconds later to make one more attempt
                  setState(() {
                      isLoaded = false;
                  });
              });
          return;
        }
    // here goes the code to handle the result 
    items =  querySnapshot.documents.map((s) => Course.fromDb(s)).toList();
    }
person Ivan Natalchenko    schedule 30.07.2020
comment
Это ваш первый ответ, поэтому я не хочу отговаривать вас от предоставления ответов в будущем путем отрицательного голосования, но вы предлагаете очень общий временный обходной путь для повторной попытки в качестве исправления ошибки в конкретной framework, не говоря уже о том, что вы написали его на другом языке, поэтому, даже если пользователь посчитал общую идею полезной, она все равно может быть на языке, который он / она действительно не понимает и т. д.) Попробуйте подумать о необходимом использовании -случаев, установка спящего режима / тайм-аута или любого другого вида задержки процесса никогда не является лучшим решением, поэтому это даже хуже, когда предлагается в качестве общего обходного пути - person Samer Murad; 30.07.2020
comment
Вдобавок ко всему, этот ответ обновлялся пару раз, то, как вы написали свой ответ, предполагает, что вы действительно не читали полный вопрос, если пользователь уже заявляет, что это ошибка, разработчики фреймворка проинформированы и работают на исправление, поэтому ваш вклад в основном сбивает с толку и не очень полезен. - person Samer Murad; 30.07.2020
comment
Привет, Самер Мурад, хорошо, я понимаю твою точку зрения. Да, я знаю, что разработчик фреймворка работает над исправлением, и, конечно, исправления с повторной попыткой на основе времени - не лучшее решение. Но с другой стороны: 1. Я не видел других предлагаемых решений проблемы (если вы знаете какие-либо - не могли бы вы предоставить ссылку? Было бы очень признательно) 2. Разработчик фреймворка еще не исправил проблему, но ошибки в приложениях надо исправлять - person Ivan Natalchenko; 31.07.2020

это может помочь

Джава:

FirebaseFirestore db = FirebaseFirestore.getInstance();

//to reconnect
db.terminate();
db = FirebaseFirestore.getInstance();

Котлин:

var db = Firebase.firestore

//to reconnect
db.terminate()
db = Firebase.firestore
person Mhmd Yaseen    schedule 10.12.2020