web-dev-qa-db-ja.com

Firebase Auth-ネットワークエラー(タイムアウト、接続の中断、ホストへの到達不能など)が発生しました

更新

私のアプリは、ライブアプリでこのクラッシュを継続的に受けています。 1週間あたり100〜200件のクラッシュがあります。だから私はこの質問に報奨金を始めています。誰かがそれを解決した場合。助けてください。

ただし、99%のユーザーはクラッシュしません。これらのクラッシュは、play-storeでのアプリのリポジトリに影響している可能性があります。解決策が見つからない場合は、この機能を最後に削除して、FirebaseAuthのメール/パスワードでログインします:/

問題:

Android app Firebase Auth Login)で多くのクラッシュ(249ユーザーからの295クラッシュ)が発生しました。メールパスワードでログインしようとした1〜2%のユーザーがこのクラッシュを起こしています。このエラーについて調査しましたそして、これは、play-serviceが実行されていないときに発生するというヒントを得ました この答え

FYI google/facebook authは完全に実行されています。この問題は、電子メールパスワードによるログインでのみ発生します。

私が試したことは?

ログインメソッドにtry-catchブロックを配置しようとしました。この例外をキャッチしようとしました。解決策として、play-serviceが実行されていないことをユーザーに通知することについてダイアログを表示することを考えました。そして、play-storeを手動で開いて、play-serviceを開始してから、これに戻ることができます。

しかし、Fabricで確認できるように、クラッシュがブロックをキャッチすることはなく、この例外が発生するとアプリがクラッシュします。このエラーはFirebaseAuth SDKでスローされるためです。

何が必要ですか?

まず、この例外の理由を確認してください。 play-serviceが実行されていないためにこれが発生した場合、ユーザーにダイアログを表示したいと思います。現在は表示されず、以下の例外の後でクラッシュします。

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());
                }
            }
        });
    }
10
Khemraj

このコードを試してください

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();
                }
            }
        });
    }

お役に立てれば幸いです。

ありがとうございました。

4
Hardik Talaviya

addOnCompleteListenerを使用する場合は、常にtaskが成功したかどうかを確認する必要があります。

以下を試してください、

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!
}

getResultメソッドのtryLoginからエラーをスローしているエラースタックトレースに基づいて、この回答を書いています。

+addOnCompleteListenerasynchronousメソッドなので、そのような例外はキャッチしません。

2
wonsuc