android - Firebase 身份验证 - 发生网络错误(例如超时、连接中断或无法访问主机)
问题描述
更新
我的应用程序在实时应用程序中不断出现这种崩溃。每周有 100-200 次崩溃。所以我开始在这个问题上悬赏。如果有人解决了。请帮忙。
然而,99% 的用户没有崩溃。这些崩溃可能会影响我的应用在 Play-store 上的存储库。因此,如果我没有得到解决方案,那么我最终将删除此功能以在 FirebaseAuth 中通过电子邮件/密码登录:/
问题:
我在 Android 应用 Firebase Auth Login 中遇到了很多崩溃(来自 249 名用户的 295 次崩溃)。1-2% 尝试通过电子邮件密码登录的用户会遇到此崩溃。我研究了这个错误并得到提示,当播放服务未按此答案运行时会发生这种情况。
仅供参考 google/facebook auth 运行良好。此问题仅在通过电子邮件密码登录时出现。
我试过什么?
我试图在登录方法上放置一个 try-catch 块。并试图捕捉到这个异常。作为解决方案,我想显示一个关于通知用户播放服务未运行的对话框。而且他可以手动打开play-store启动play-service,然后再访问这个。
但正如我在 Fabric 上看到的那样,崩溃永远不会出现在 catch 块中,并且在发生此异常时应用程序会崩溃。因为这个错误是在 FirebaseAuth SDK 中抛出的。
需要什么?
首先,我想确定这个异常的原因。如果由于播放服务未运行而发生这种情况,那么我想向用户显示一个对话框。当前从未显示,并且在以下异常后崩溃。
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)
代码
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());
}
}
});
}
解决方案
试试这个代码
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();
}
}
});
}
我希望这可以帮助你!
谢谢你。
推荐阅读
- windows - 如何居中或设置 Xbox 游戏栏小部件的位置?
- sql - SQL:创建一个以最近 3 天日期为值的额外列
- python - 如何在 sympy 中绘制求解方程的结果?
- python - Python 单元测试 - 'gcsfs.utils.HttpError: Anonymous caller does not have storage.objects.list access to the Google Cloud Storage bucket。'
- r - 将 R 连接到 ServiceNow ODBC
- python - 不和谐.py | 如何只检查作者信息?
- matlab - 如何测试 ODE 积分是否达到平衡?
- python - 如何根据 2 个数据框中的“日期”列和“列表”列获取结果?
- xamarin - 无法解析 System.Int32 Xamarin.Essentials.Resource/Id::accessibility_action_clickable_span
- python - 如何从列表中的索引 1 开始并在列表中的最后一个元素之前结束