Update
My app is continuously getting this crash in live app. There are 100-200 crash per week. So I am starting a bounty on this question. If someone have solved it. Please help.
However 99% users are crash free. These crashes may be effecting my app's repo on play-store. so if I don't get solution, then I will finally remove this feature to login by email/password in FirebaseAuth :/
Problem:
I got many crashes (295 crashes from 249 users) in Android app Firebase Auth Login. 1-2% users who are trying login by email-password are getting this crash. I researched for this error and got hint that this occur when play-service is not running by this answer.
FYI google/facebook auth is running perfectly. This issue is in Login via email-password only.
What I have tried?
I tried to put a try-catch block on the login method. and tried to catch this exception. As the solution I thought to show a dialog about informing user that play-service is not running. And he can manually open play-store to start play-service, and then visit back this.
But as I can see on Fabric, crashes never come to catch block, and the app crashes when this exception occur. Because this error is thrown in FirebaseAuth SDK.
What is needed?
First I want be sure about the reason of this exception. If this occur due to play-service not running, then I want to show user a dialog. Which never shows currently, and it crashes after below exception.
Fatal Exception: com.google.android.gms.g.f: com.google.firebase.e: A network error (such as timeout, interrupted connection or unreachable host) has occurred.
at com.google.android.gms.tasks.zzu.getResult(Unknown Source)
at com.startech.dreamteam11.app.activities.ActivityLogin.tryLogin(Unknown Source)
at com.startech.dreamteam11.app.activities.ActivityLogin.lambda$-wlX6lv_j3Q0nUN9OuqzHS7ZGP4(Unknown Source)
at com.startech.dreamteam11.app.activities.-$$Lambda$ActivityLogin$-wlX6lv_j3Q0nUN9OuqzHS7ZGP4.onComplete(lambda)
at com.google.android.gms.tasks.zzj.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:145)
at android.app.ActivityThread.main(ActivityThread.java:6946)
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:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Code
private void loginViaEmailPassword(String email, String pass) {
showProgressBar();
try {
// check if user is registered. then try login
FirebaseAuth.getInstance().fetchSignInMethodsForEmail(email).addOnCompleteListener(task -> {
SignInMethodQueryResult result = task.getResult();
if (task.isSuccessful() && result != null && result.getSignInMethods() != null && result.getSignInMethods().size() > 0) {
// user is registered, now try login
tryLogIn(email, pass, new OnFireBaseLogin() {
@Override
public void onSuccess(FirebaseUser user) {
// check if email is verified, if not send verification email.
if (user.isEmailVerified()) {
// user is verified, redirect to main screen
startMainActivity();
} else {
sendVerificationEmail(user, task1 -> {
hideProgressBar();
FirebaseAuth.getInstance().signOut();
if (task1.isSuccessful()) {
Utilities.getInstance().showDialog(ActivityLogin.this, getString(R.string.sent_verification_email), getString(R.string.msg_sent_verification_email), (dialog, which) -> {
dialog.dismiss();
});
} else {
errorMessage(getString(R.string.msg_error_sending_email));
}
});
}
}
@Override
public void onError(int error, @Nullable Throwable exception) {
hideProgressBar();
assert exception != null;
{
App.getInstance().logException(new Exception(exception), getClass());
errorMessage(exception.getMessage());
}
}
});
} else {
hideProgressBar();
errorMessage(getString(R.string.msg_email_not_registered));
}
});
} catch (Exception e) {
hideProgressBar();
App.getInstance().logException(e, getClass(), true);
Utilities.getInstance().showDialog(this, getString(R.string.some_error_occurred), getString(R.string.msg_fail_login_play_service)).show();
}
}
public void tryLogIn(String email, String pass) {
FirebaseAuth.getInstance().signInWithEmailAndPassword(email, pass).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
if (task.isSuccessful() && currentUser != null) {
Log.w(TAG, "signInWithCustomToken:success", task.getException());
successResponse(currentUser);
} else {
Log.w(TAG, "signInWithCustomToken:failure", task.getException());
errorResponse(0, task.getException());
}
}
});
}
Try this code
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Validation.loginValidation(edtEmail, edtPass)) {
loginFirebase(edtEmail.getText().toString(), edtPass.getText().toString(), firebaseAuth);
}
}
});
public void loginFirebase(String email, String pass, FirebaseAuth firebaseAuth) {
progressDialog.setTitle("Please Wait.....");
progressDialog.setMessage("Processing....");
progressDialog.setCancelable(false);
progressDialog.show();
(firebaseAuth.signInWithEmailAndPassword(email, pass)).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
progressDialog.dismiss();
Toast.makeText(getActivity(), "Login Successful", Toast.LENGTH_LONG).show();
Intent i = new Intent(getActivity(), DrawerMain.class);
startActivity(i);
edtEmail.setText("");
edtPass.setText("");
} else {
Log.e("Error", task.getException().toString());
Toast.makeText(getActivity(), task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
}
});
}
I hope that can help you!
Thank You.
When you use addOnCompleteListener
, you always need to check if the task
is successful.
Try the follow,
somethingTask().addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
Log.wtf(TAG, "somethingTask:ERROR", task.getException());
return;
}
Log.i(TAG, "somethingTask:SUCCESS");
// Now we are logged in, let's write next code!
}
I'm writing this answer based on your error stack trace which is throwing the error from getResult
in the tryLogin
method.
+ You won't catch the exception like that kind of way, since addOnCompleteListener
is an asynchronous
method.
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