firebase / firebase-android-sdk

Firebase Android SDK
https://firebase.google.com
Apache License 2.0
2.27k stars 575 forks source link

Firebase Auth signInWithCredentials Blocking Indefinitely/Not Failing #2765

Open GEverding opened 3 years ago

GEverding commented 3 years ago

[READ] Step 1: Are you in the right place?

Issues filed here should be about bugs in the code in this repository. If you have a general question, need help debugging, or fall into some other category use one of these other channels:

[REQUIRED] Step 2: Describe your environment

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

For 5000+ users per day signinWithCredential is never completing/erroring when using listeners. If I instead call Task.await with a 60 second timeout the TimeoutException is thrown. Since rewriting the login code hasn't changed the behaviour we need help debugging it.

If we tell them to install Cloudflare 1.1.1.1 they can log into the app. We then ask them to disable 1.1.1.1 and relogin and it works fine. Additionally at the same time we have other API requests so we don't believe the issue is network related.

We haven't figured out to reproduce it locally. Its effecting users across the globe with no patterns to OS version or phone. What I do observe is that it either completes instantly or not at all.

It feels like there is a bug getting hit inside the auth sdk that is preventing the Task from failing/completing. Are there any logs in the SDK or a way for us to debug this because its a real issue our users are facing.

Relevant Code:

Version 1

FirebaseAuth.getInstance().signInWithCredential(credential)
  .addOnCompleteListener(taskExecutor, new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {
      if (task.isSuccessful()) {
        RaveLogging.i(LOG_TAG, "FirebaseAuth:signInWithCredential successful");
        handleFirebaseUser(FirebaseAuth.getInstance().getCurrentUser());
     } else {
       Logging.e(LOG_TAG, task.getException(), "FirebaseAuth:signInWithCredential failed");
       FirebaseCrashlytics.getInstance().recordException(task.getException());
       onLoginFailure(FIREBASE_AUTH_ERROR_CODE, getString(R.string.auth_failed));
     }
   }
});

Version 2

try {
  Tasks.await(FirebaseAuth.getInstance().signInWithCredential(credential), 60, TimeUnit.SECONDS);
  Logging.i(LOG_TAG, "FirebaseAuth:signInWithCredential successful");
  handleFirebaseUser(FirebaseAuth.getInstance().getCurrentUser());
  RaveLogging.i(LOG_TAG, "FirebaseAuth task succeeded: signInWithFirebase");
} catch (ExecutionException | InterruptedException | TimeoutException e) {
  RaveAnalytics.sendUniqueEvenAnalytics(new PlaybackInfo(), "nonfatal", "FIREBASE_AUTH_TIMEOUT", e.getMessage());
  ogging.e(LOG_TAG, e, "Await FirebaseAuth:signInWithCredential failed with exception: " + e.getMessage());
  FirebaseCrashlytics.getInstance().recordException(e);
  onLoginFailure(FIREBASE_AUTH_ERROR_CODE, getString(R.string.auth_failed));
   Logging.i(LOG_TAG, "GoogleAuthServer task failed: signInWithFirebase");
}
google-oss-bot commented 3 years ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

yuchenshi commented 3 years ago

Hi, thanks for filing this issue! We are unable to promise any timeline for this, but if others also have this issue, adding a +1 on this issue can help us prioritize adding this to the roadmap.

(Googler-only internal tracking bug: b/192411054)

GEverding commented 3 years ago

Exploring other Android SDK bugs and came across this issue where one of the comments is very similar to what we see.

avolkovi commented 3 years ago

Thanks for linking, I checked with @malcolmdeck about this and we have been unable to reliably reproduce the linked issue. Unfortunately without a way to reproduce on our side we can't identify a fix

j22purikas commented 2 years ago

Any updates? This issue is causing quite a problem for us, unfortunately.

j22purikas commented 2 years ago

@GEverding, have you fixed your issues somehow?

LightWeek commented 2 years ago

Is there any fix for the issue? Unfortunately still facing this in our app. But in our case, it happens while getting an id token.

val user = FirebaseAuth.getInstance().currentUser
Tasks.await(user.getIdToken(false), timeoutMillis, TimeUnit.MILLISECONDS)
pistolcaffe commented 2 years ago

I have same issue. it happens while getting an id token. It use to API Authrization key, critical our app.

FirebaseAuth.getInstance().currentUser?.getIdToken(true)?.await()?.token

YSDC commented 1 year ago

I also face this indefinitely blocking state, and I was able to reproduce it by proxying my connection:

So, what should we do? Why is timeout ignored?

inteist commented 1 year ago

+1 this started recently after updating auth libraries both Firebase and login providers (Google and Facebook)

bhparijat commented 1 year ago

@inteist What's the new version being used?

inteist commented 1 year ago

I did a downgrade to 21.1 (?) (BoM 31.3.0) from BoM (31.5.0) since this was the last version where it was fine BUT it did not help. It's not the version.

I think I may have gotten to what the issue is (still unconfirmed as I just released an update)

Previous (WORKING code)

    fun getToken(completion: (String?) -> Unit) {
        val currentUser = FirebaseAuth.getInstance().currentUser

        val forceRefreshParam = false
        currentUser?.getIdToken(forceRefreshParam)
            ?.addOnSuccessListener {
                completion(it.token)
            }?.addOnFailureListener {
                Timber.e(it, "Can't get FirAuth token")
                completion(null)
            }
    }

new NON working code:

    suspend fun getIdToken(): String? {
        FirebaseAuth.getInstance().currentUser?.let { firebaseUser ->
            return firebaseUser.getIdToken(false).await().token
        } ?: run {
            Timber.e("Can't get FirAuth token")
            return null
        }
    }

I wanted an improved code without the callback but apparently this seems to create an issue.

Again, I am not sure this is the problem. I am rolling out a release where I rolled back that change.

Thanks.

bhparijat commented 1 year ago

Hi @YSDC, could you please provide your charles proxy logs. It would be good to know what network requests are failing.

@inteist Do you have any logs for network requests?

malenalbc commented 3 months ago

~~This is happening to me too using Firebase version: com.google.firebase:firebase-bom:32.7.2 com.firebaseui:firebase-ui-auth:8.0.2~~

val credential = GoogleAuthProvider.getCredential(...)
FirebaseAuth.signInWithCredential(credential)
  .addOnCanceledListener(activity) { 
    // onCancel 
  }
  .addOnFailureListener(activity) { 
    // onError 
  }
  .addOnSuccessListener(activity) { 
    // Do Stuff
  }
  .addOnCompleteListener(activity) { task ->
    // Do Stuff
  }

When calling this and inmediatly putting the app in foreground, the activity gets paused but not stopped. No listener is called when resuming the app, so the process goes forever waiting for an answer. Ideally, we'd have more control and be able to cancel the task when needed.

Nevermind, the activity did get stopped. Since I'm using navigation component, I was avoiding signing in the onStart of the fragment so recreations wouldn't affect it. Coming back to the screen was waiting for listeners that were already cancelled.