Exceção não capturada no runloop do Firebase (3.0.0) relacionada a persistência e consultas
Já estou lutando com essa exceção há um tempo. Um segmento relevante no grupo firebase está meio mortohttps://groups.google.com/forum/#!topic/firebase-talk/iy0762S3KsU, também dois relacionados ao SO não são respondidos:Exceção não capturada no runloop do Firebase (3.0.0) eExceção não capturada no runloop do Firebase (3.0.0). Por favor, reporte para [email protected]
A solução alternativa para desativar a persistência do banco de dados funciona, mas não é inaceitável para aplicativos que exigem capacidade offline.
Eu preparei um exemplo de atividade mínima que reproduz a exceção no meu ambiente. Tudo se resume a ler o banco de dados com consultas. É o suficiente para iniciar e encerrar ("encerrar" no Android Studio, não apenas sair) a atividade três vezes (estranho) e no terceiro lançamento, ele trava com a seguinte série espetacular de exceções (quanto mais consultas na fila, mais exceções eu acho ):
07-05 18:47:10.132 20291-20291/com.mypackage D/ChimeraFileApk: Classloading successful. Optimized code found.
07-05 18:47:10.154 20291-20381/com.mypackage E/RunLoop: Uncaught exception in Firebase runloop (3.0.0). Please report to [email protected]
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:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
07-05 18:47:10.154 20291-20291/com.mypackage D/AndroidRuntime: Shutting down VM
07-05 18:47:10.155 20291-20291/com.mypackage E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mypackage, PID: 20291
java.lang.RuntimeException: Uncaught exception in Firebase runloop (3.0.0). Please report to [email protected]
at com.google.android.gms.internal.zzadphttps://groups.google.com/forum/#!topic/firebase-talk/iy0762S3KsU1.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:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
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:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
07-05 18:47:10.165 20291-20381/com.mypackage E/RunLoop: Uncaught exception in Firebase runloop (3.0.0). Please report to [email protected]
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.google.android.gms.internal.zzafj.zzg(com.google.android.gms.internal.zzaew)' on a null object reference
at com.google.android.gms.internal.zzafc.zzf(Unknown Source)
at com.google.firebase.database.Query$3.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
07-05 18:47:10.166 20291-20381/com.mypackage E/RunLoop: Uncaught exception in Firebase runloop (3.0.0). Please report to [email protected]
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.google.android.gms.internal.zzafj.zzg(com.google.android.gms.internal.zzaew)' on a null object reference
at com.google.android.gms.internal.zzafc.zzf(Unknown Source)
at com.google.firebase.database.Query$3.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
07-05 18:47:10.173 20291-20381/com.mypackage E/RunLoop: Uncaught exception in Firebase runloop (3.0.0). Please report to [email protected]
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.internal.zzafg.zzg(com.google.android.gms.internal.zzafa, com.google.android.gms.internal.zzahu)' on a null object reference
at com.google.android.gms.internal.zzafc.zzb(Unknown Source)
at com.google.android.gms.internal.zzafc.zza(Unknown Source)
at com.google.android.gms.internal.zzafc.zzaO(Unknown Source)
at com.google.firebase.database.connection.idl.IPersistentConnectionImpl$3.zzaO(Unknown Source)
at com.google.firebase.database.connection.idl.zzi$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:387)
at alx.a(:com.google.android.gms.DynamiteModulesC:196)
at amb.a(:com.google.android.gms.DynamiteModulesC:330)
at akh.a(:com.google.android.gms.DynamiteModulesC:3591)
at amf.a(:com.google.android.gms.DynamiteModulesC:386)
at aln.onTransact(:com.google.android.gms.DynamiteModulesC:50)
at android.os.Binder.transact(Binder.java:387)
at com.google.firebase.database.connection.idl.zzf$zza$zza.zzhT(Unknown Source)
at com.google.firebase.database.connection.idl.IPersistentConnectionImplExceção não capturada no runloop do Firebase (3.0.0). Por favor, reporte para [email protected](Unknown Source)
at com.google.android.gms.internal.zzaeuhttps://groups.google.com/forum/#!topic/firebase-talk/iy0762S3KsU1.zzhT(Unknown Source)
at com.google.android.gms.internal.zzadn$1.onFailure(Unknown Source)
at com.google.android.gms.tasks.zzd$1.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:269)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
07-05 18:47:11.745 20291-20291/com.mypackage I/Process: Sending signal. PID: 20291 SIG: 9
A falha ocorre na primeira tentativa de leitura após obter a referência ao banco de dados e concluir a persistência.
Aqui está a atividade:
public class TestRunloopException extends AppCompatActivity {
private static final String TAG = "test";
private Handler mHandler = new Handler();
Runnable mReadScoresRunnable = new Runnable() {
@Override
public void run() {
readScores();
mHandler.postDelayed(mReadScoresRunnable, 5000);
}
};
@Override
protected void onStart() {
super.onStart();
mHandler.postDelayed(mReadScoresRunnable, 3000);
}
void readScores() {
DatabaseReference scoresRef = getDatabase().getReference("scores");
//it occurs even with a single query..
//scoresRef.startAt(51).limitToFirst(3).addListenerForSingleValueEvent(new MyValueListener());
scoresRef.endAt(50).limitToLast(4).addListenerForSingleValueEvent(new MyValueListener());
}
public static class MyValueListener implements ValueEventListener {
@Override
public void onDataChange(DataSnapshot data) {
Log.d(TAG, "onDataChange: " + data.getValue());
}
@Override
public void onCancelled(DatabaseError error) {
Log.d(TAG, "onCancelled: " + error.getMessage());
}
}
// access-wrapper, set persistence only once
private static FirebaseDatabase mDatabase;
public static FirebaseDatabase getDatabase() {
if (mDatabase == null) {
mDatabase = FirebaseDatabase.getInstance();
mDatabase.setPersistenceEnabled(true);
}
return mDatabase;
}
}
O nó "scores" não possui configurações de segurança específicas:"scores": { ".read": true, ".write": true } ...
Testado com firebase - *: 9.0.2, mas o bug também foi observado no 9.2.0.
Como evitar a falha ao usar várias consultas na mesma referência / nó e, é claro, ter persistência?