I'm using the latest 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'
Project build.gradle
classpath 'com.google.gms:google-services:3.0.0'
And after some time application starts crashing with this Exception:
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 I have:
@Override
public void onCreate() {
...
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
}
and also we created singleton helper class for Firebase what called from Activities(all activities in the same process)/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:2.5.6@aar') {
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:0.4.3@aar'
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')
}
UPDATE: It turns out there's another cause of this symptom, as mentioned by Kristijan in the comments. We've identified a bug where if you have a startAt() or endAt() call with an integer endpoint, e.g. startAt(10), it can trigger this sort of cache corruption. This bug will be fixed in the next release of the SDK. In the meantime, you may be able to use non-integer endpoints, e.g. startAt(10.001), as a workaround.
These symptoms match a known limitation with Firebase Realtime Database that prevents it from working if you have persistence enabled in multiple processes in an Android app.
Note that any Application.onCreate()
code will run for every process in a multi-process android app, and so if your app is multi-process, you are initializing Firebase Database with persistence enabled in multiple processes and this is liable to lead to corruption of our offline cache and the hardAssert error that you are reporting.
Keep in mind that sometimes your app may be multi-process without you realizing it. For instance if you're using firebase-crash, it currently creates a background process for the purpose of reporting crashes more reliably, and so if you use firebase-crash, you now have a multi-process app. Other 3rd-party libraries could have similar behavior.
To test, you could add code to your Application.onCreate() something like:
System.out.println('INITIALIZING APP FROM PID: ' + android.os.Process.myPid());
If you see that logged twice in logcat (with two different PIDs) that means your app is running with multiple processes and you're hitting the limitation I mentioned.
As a workaround, you can either:
setPersistenceEnabled()
code from your Application class and put it somewhere that will only be executed in your main process.Note that you'll likely need to clear your app data to get rid of the hardAssert error once you've hit it, as the error indicates that the offline cache has gotten into an invalid state, so to fix it, you must clear it completely.
In an upcoming release, we have added better detection of this scenario so you'll get a much better error message. Additionally, firebase-crash will in the future avoid spawning a 2nd process, which may make this less likely to be an issue.
I know it is an old post , i faced this issue and after some research , i upgraded my gradle to : implementation 'com.google.firebase:firebase-database:18.0.1' This helped the error go away. use the latest library. This Solved My Problem.
We are facing the same issue on version 9.0.2
and 9.2.0
. After many hours of investigation, we found that one way to reproduce this issue is to have a query with fixed endAt
and startAt
parameters. Let me explain with a sample code:
// 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);
}
});
}
}
So the fixed endAt
param will crash the app on third start. I assume queries are cached to disk and then corrupted at some point if we recreate the same query from local cache multiple times (three). On the other hand, if endAt
is not fixed, for example current time in millis, then everything works as expected. The same applies for startAt
query parameter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With