Подтвердить что ты не робот

Исключение исключения в Firebase runloop (3.0.0)

Я использую последнюю firebase (9.0.2): build.gradle:

dependencies {
     ...
     compile "com.google.firebase:firebase-database:9.0.2"
     compile 'com.google.firebase:firebase-auth:9.0.2'
}
apply plugin: 'com.google.gms.google-services'

Проект build.gradle

classpath 'com.google.gms:google-services:3.0.0'

И через некоторое время приложение начинает сбой с помощью этого исключения:

  Fatal Exception: java.lang.RuntimeException: Uncaught exception in Firebase runloop (3.0.0). Please report to [email protected]
       at com.google.android.gms.internal.zzadp$1$1.run(Unknown Source)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5274)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
Caused by java.lang.AssertionError: hardAssert failed: 
       at com.google.android.gms.internal.zzaiv.zzb(Unknown Source)
       at com.google.android.gms.internal.zzaiv.zzaN(Unknown Source)
       at com.google.android.gms.internal.zzagh.zzb(Unknown Source)
       at com.google.android.gms.internal.zzagh.<init>(Unknown Source)
       at com.google.android.gms.internal.zzaga.<init>(Unknown Source)
       at com.google.android.gms.internal.zzaga.<init>(Unknown Source)
       at com.google.android.gms.internal.zzadp.zza(Unknown Source)
       at com.google.android.gms.internal.zzaeu.zzic(Unknown Source)
       at com.google.android.gms.internal.zzafc.zzRy(Unknown Source)
       at com.google.android.gms.internal.zzafc.zza(Unknown Source)
       at com.google.android.gms.internal.zzafc$1.run(Unknown Source)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
       at java.lang.Thread.run(Thread.java:818)

in onCreate of Application У меня есть:

@Override
    public void onCreate() {
    ...
    FirebaseDatabase.getInstance().setPersistenceEnabled(true);
}

а также создан вспомогательный класс singleton для Firebase, который вызван из Activity (все действия в одном процессе)/Fragments:

 private FirebaseHelper() {
        mFirebaseRef = FirebaseDatabase.getInstance().getReference();
        mFirebaseAuth = FirebaseAuth.getInstance();
        mFirebaseAuth.addAuthStateListener(this);
        authentication();
    }

    public static synchronized FirebaseHelper getInstance() {
        if (mInstance == null || mInstance.getFirebaseRef() == null) {
            mInstance = new FirebaseHelper();
        }
        return mInstance;
    }

Libraries:

dependencies {
    testCompile 'junit:junit:4.12'
    compile('com.crashlytics.sdk.android:crashlytics:[email protected]') {
        transitive = true;
    }
    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.android.support:support-v4:23.4.0'
    compile 'com.android.support:support-v13:23.4.0'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support:design:23.4.0'
    compile 'com.android.support:support-annotations:23.4.0'
    compile 'com.android.support:gridlayout-v7:23.4.0'
    compile 'com.google.android.gms:play-services-base:9.0.2'
    compile 'com.google.android.gms:play-services-maps:9.0.2'
    compile 'com.google.android.gms:play-services-location:9.0.2'
    compile 'com.google.android.gms:play-services-appindexing:9.0.2'
    compile 'com.google.android.gms:play-services-analytics:9.0.2'
    compile 'com.google.firebase:firebase-messaging:9.0.2'
    compile 'com.facebook.android:facebook-android-sdk:4.11.0'
    compile 'de.greenrobot:eventbus:2.4.0'
    compile 'com.amazonaws:aws-android-sdk-core:2.2.12'
    compile 'com.amazonaws:aws-android-sdk-cognito:2.2.12'
    compile 'com.amazonaws:aws-android-sdk-s3:2.2.12'
    compile 'com.android.support:multidex:1.0.1'
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
    compile 'io.reactivex:rxandroid:1.2.0'
    compile 'io.reactivex:rxjava:1.1.5'
    compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
    compile 'com.github.curioustechizen.android-ago:library:1.3.0'
    compile 'com.cedarsoftware:json-io:4.4.0'
    compile 'com.timehop.stickyheadersrecyclerview:library:[email protected]'
    compile 'joda-time:joda-time:2.9.3'
    compile 'com.facebook.fresco:fresco:0.10.0'
    compile 'com.facebook.fresco:imagepipeline-okhttp3:0.10.0'
    compile 'com.google.firebase:firebase-core:9.0.2'
    compile 'com.google.firebase:firebase-invites:9.0.2'
    compile 'com.google.firebase:firebase-database:9.0.1'
    compile 'com.google.firebase:firebase-auth:9.0.1'
    compile 'com.github.jd-alexander:LikeButton:0.2.0'

    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
    androidTestCompile 'junit:junit:4.12'
    androidTestCompile 'com.android.support:support-annotations:23.4.0'
    androidTestCompile 'com.android.support.test:runner:0.5'
    androidTestCompile 'com.android.support.test:rules:0.5'
    compile files('libs/core-3.2.1.jar')
}
4b9b3361

Ответ 1

Мы сталкиваемся с той же проблемой в версии 9.0.2 и 9.2.0. После многих часов исследования мы обнаружили, что одним из способов воспроизвести эту проблему является запрос с фиксированными параметрами endAt и startAt. Позвольте мне объяснить пример кода:

// Firebase dependencies
compile 'com.google.firebase:firebase-core:9.2.0'
compile 'com.google.firebase:firebase-database:9.2.0'

...

public class MainActivity extends AppCompatActivity {

    private FirebaseDatabase m_Database;
    private static boolean s_persistenceInitialized = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        m_Database = FirebaseDatabase.getInstance();

        if (!s_persistenceInitialized) {
            m_Database.setPersistenceEnabled(true);
            s_persistenceInitialized = true;
        }

        m_Database.setLogLevel(Level.DEBUG);
    }

    @Override
    protected void onStart() {
        super.onStart();

        long endAt = 100L; // Fixed value: CRASH on third app restart
    //  long endAt = new Date().getTime(); // Dynamic value: NO CRASH
        getGoal("min_per_day", endAt, "some_uid");
    }

    private void getGoal(String p_goalId, long p_endAt, String p_uid) {
        Query ref = m_Database.getReference("v0/data/meditation/goals").child(p_goalId).child(p_uid)
            .orderByChild("time").endAt(p_endAt).limitToLast(1);

        ref.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Log.i("FB", "Snapshot: " + dataSnapshot);
            }

            @Override
            public void onCancelled(DatabaseError error) {
                Log.e("FB", "Error: " + error);
            }
        });
    }
}

Таким образом, фиксированный параметр endAt приведет к сбою приложения при третьем запуске. Я предполагаю, что запросы кэшируются на диск, а затем повреждены в какой-то момент, если мы повторно создаем один и тот же запрос из локального кеша несколько раз (три). С другой стороны, если endAt не фиксировано, например текущее время в миллисекундах, то все работает так, как ожидалось. То же самое относится к параметру запроса startAt.

Ответ 2

ОБНОВЛЕНИЕ: Оказывается, есть еще одна причина этого симптома, о чем упоминал Кристиян в комментариях. Мы обнаружили ошибку, если у вас есть вызов startAt() или endAt() с конечной точкой целого числа, например. startAt (10), он может вызвать подобное повреждение кеша. Эта ошибка будет исправлена ​​в следующей версии SDK. Тем временем вы можете использовать нецелые конечные точки, например. startAt (10.001), как обходной путь.

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

Обратите внимание, что любой код Application.onCreate() будет запускаться для каждого процесса в многопроцессорном андроидном приложении, поэтому, если ваше приложение является многопроцессорным, вы инициализируете базу данных Firebase с возможностью сохранения в нескольких процессах, и это может привести к к повреждению нашего автономного кеша и ошибке hardAssert, о которой вы сообщаете.

Имейте в виду, что иногда ваше приложение может быть многопроцессным, если вы его не осознаете. Например, если вы используете firebase-crash, в настоящее время он создает фоновый процесс с целью более достоверной отчетности об авариях, поэтому, если вы используете аварийный сбой firebase, у вас теперь есть приложение с несколькими процессами. Другие сторонние библиотеки могут иметь подобное поведение.

Чтобы проверить, вы можете добавить код в свой Application.onCreate() что-то вроде:

System.out.println('INITIALIZING APP FROM PID: ' + android.os.Process.myPid());

Если вы видите, что дважды регистрировались в logcat (с двумя разными PID), что означает, что ваше приложение работает с несколькими процессами, и вы используете ограничение, о котором я упоминал.

В качестве обходного пути вы можете:

  • Измените свое приложение так, чтобы он использовал только один процесс.
  • Удалите код setPersistenceEnabled() из класса Application и поместите его где-нибудь, который будет выполнен только в вашем основном процессе.

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

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

Ответ 3

Я тоже столкнулся с той же проблемой; По прошествии некоторого времени приложение прерывалось при каждом запуске. На данный момент я отключил эту базу данных. FirebaseDatabase.getInstance().setPersistenceEnabled(true).

Я не вижу таких странных сбоев сейчас!

Команда Hope Firebase скоро решит эту проблему.

Ответ 4

Эта проблема исправлена ​​в версии 9.6. Ознакомьтесь с примечаниями .

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

Ответ 5

Я знаю, что это старый пост, я столкнулся с этой проблемой, и после некоторых исследований, я обновил свой Gradle до:    реализация 'com.google.firebase: база данных firebase: 18.0.1' Это помогло устранить ошибку. использовать последнюю библиотеку. Это решило мою проблему.

Ответ 6

Только для записи:

Мы решили Uncaught exception in Firebase runloop (3.0.0) выполнить удаление следующей строки

//remove this "feature" if you should use it
FirebaseApp.setAutomaticResourceManagmentEnabled(true)

Описание API:

Если установлено значение true, это означает, что Firebase должен закрыть базу данных когда приложение находится в фоновом режиме. Отключено по умолчанию.

(Возможно, мы упустили некоторые конфигурации для правильного использования этой функции, но приложение работает так, как ожидается, после того, как не включит ResourceManagment)

Ответ 7

У меня есть эта проблема, этот метод работает, если установка является новой, и этот метод работает, если поставить код как:

        FirebaseDatabase.getInstance().setPersistenceEnabled(true);
        FirebaseDatabase database = FirebaseDatabase.getInstance();

Но если тест в другом устройстве вам нужно удалить приложение