'Firebase Task is not yet complete

I am getting following exception randomly after signing out of Firebase using FirebaseAuth.getInstance().signOut(); and signing in again

I am trying to get the token from FirebaseUser after the user is successfully authenticated signUpRequest.firebaseToken = user.getIdToken(true).result?.token

user is the FirebaseUser received after authentication

E/AndroidRuntime: FATAL EXCEPTION: main
   Process: agrahyah.keen, PID: 12082
   java.lang.IllegalStateException: Task is not yet complete 
       at com.google.android.gms.common.internal.zzbp.zza(Unknown Source)
       at com.google.android.gms.tasks.zzn.zzbic(Unknown Source)
       at com.google.android.gms.tasks.zzn.getResult(Unknown Source)
       at com.xxxActivity.makeSignUpRequest(xxxActivity.kt:129)
       at com.xxxActivity.access$makeSignUpRequest(xxxActivity.kt:36)
       at com.xxxActivity$signInAnonymously$1.onComplete(xxxActivity.kt:94)
       at com.google.android.gms.tasks.zzf.run(Unknown Source)
       at android.os.Handler.handleCallback(Handler.java:751)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6077)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

I am using Firebase android sdk version 11.2.2. This error never occured on previous versions of the Firebase SDK



Solution 1:[1]

Try to receive result asynchronously (through .addOnSuccessListener{...}) or check flag isSuccessful from Task.

Solution 2:[2]

I tried the answers above but implementing OnSuccessListener or OnCompleteListener doesn't give my calling thread a way to wait until the task is complete. task.getResult is supposed to wait, but for some reason, it was sporadially exiting with the exception above.

Finally, the code below seems to have fixed it:

tokenTask = firebaseUser.getIdToken(false);
Tasks.await(tokenTask);
@NotNull GetTokenResult tokenResult = Objects.requireNonNull(tokenTask.getResult());

In short, I am explicitly waiting for the task to complete and then calling task.getResult. Only calling Tasks.await(tokenTask) without calling task.getResult does not seem to work either, as Tasks.await(tokenTask) somehow seems to exit before the task is complete. I am not sure why calling both is working.

By the way, putting a breakpoint in the debugger causes the code to work because it gives the task time to complete, so this is a bit hard to debug.

Solution 3:[3]

I solved this using the Kotlin+Coroutine extensions for Google Play Services:

// gradle
dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.3.6'
}
// code
val token = user.getIdToken(true).await().token

Solution 4:[4]

You can use the SnapShotListener, just like recomended on Firebase's docs:

final DocumentReference docRef = db.collection("users").document("id");
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
     @Override
     public void onEvent(@Nullable DocumentSnapshot snapshot,
                         @Nullable FirebaseFirestoreException e) {
           if (e != null) {
               Log.w(TAG, "Listen failed.", e);
               return;
           }
           if (snapshot != null && snapshot.exists()) {

               // HERE IS WHERE I GET THE MAP TO USE WHEREVER I WANT                    
               Map ds;
               ds = snapshot.getData();

               // TOAST CONFIRMS WHAT EVENT HAPPENED AND IT'S CONTENT
               Toast.makeText(ItemsListActivity.this, ds.toString(), Toast.LENGTH_SHORT).show();

               Log.d(TAG, "Current data: " + snapshot.getData());
          } else {
               Log.d(TAG, "Current data: null");
          }
     }});

Hope I've helped.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 CopsOnRoad
Solution 2 Vijayendra Vasu
Solution 3 Matt Mc
Solution 4