Firebaseを使用して、特定の例外をキャッチし、それをユーザーに優雅に伝えるにはどうすればよいですか?例:
FirebaseAuthInvalidCredentialsException:メールアドレスの形式が正しくありません。
以下のコードを使用して、電子メールとパスワードを使用してユーザーをサインアップしますが、Javaの上級者ではありません。
mAuth.createUserWithEmailAndPassword(email, pwd)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (!task.isSuccessful()) {
//H.toast(c, task.getException().getMessage());
Log.e("Signup Error", "onCancelled", task.getException());
} else {
FirebaseUser user = mAuth.getCurrentUser();
String uid = user.getUid();
}
}
});
Tryブロック内でtask.getException
によって返される例外をスローし、使用しているメソッドによってスローされる可能性のある各タイプの例外をキャッチできます。
OnCompleteListener
メソッドのcreateUserWithEmailAndPassword
の例を次に示します。
if(!task.isSuccessful()) {
try {
throw task.getException();
} catch(FirebaseAuthWeakPasswordException e) {
mTxtPassword.setError(getString(R.string.error_weak_password));
mTxtPassword.requestFocus();
} catch(FirebaseAuthInvalidCredentialsException e) {
mTxtEmail.setError(getString(R.string.error_invalid_email));
mTxtEmail.requestFocus();
} catch(FirebaseAuthUserCollisionException e) {
mTxtEmail.setError(getString(R.string.error_user_exists));
mTxtEmail.requestFocus();
} catch(Exception e) {
Log.e(TAG, e.getMessage());
}
}
@ pdegand59の回答に加えて、Firebaseライブラリでいくつかのエラーコードを見つけて、Android(返されたエラーコード)でテストします。これが役に立てば幸いです。
("ERROR_INVALID_CUSTOM_TOKEN", "The custom token format is incorrect. Please check the documentation."));
("ERROR_CUSTOM_TOKEN_MISMATCH", "The custom token corresponds to a different audience."));
("ERROR_INVALID_CREDENTIAL", "The supplied auth credential is malformed or has expired."));
("ERROR_INVALID_EMAIL", "The email address is badly formatted."));
("ERROR_WRONG_PASSWORD", "The password is invalid or the user does not have a password."));
("ERROR_USER_MISMATCH", "The supplied credentials do not correspond to the previously signed in user."));
("ERROR_REQUIRES_RECENT_LOGIN", "This operation is sensitive and requires recent authentication. Log in again before retrying this request."));
("ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL", "An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address."));
("ERROR_EMAIL_ALREADY_IN_USE", "The email address is already in use by another account."));
("ERROR_CREDENTIAL_ALREADY_IN_USE", "This credential is already associated with a different user account."));
("ERROR_USER_DISABLED", "The user account has been disabled by an administrator."));
("ERROR_USER_TOKEN_EXPIRED", "The user\'s credential is no longer valid. The user must sign in again."));
("ERROR_USER_NOT_FOUND", "There is no user record corresponding to this identifier. The user may have been deleted."));
("ERROR_INVALID_USER_TOKEN", "The user\'s credential is no longer valid. The user must sign in again."));
("ERROR_OPERATION_NOT_ALLOWED", "This operation is not allowed. You must enable this service in the console."));
("ERROR_WEAK_PASSWORD", "The given password is invalid."));
((FirebaseAuthException)task.getException()).getErrorCode()
を使用してエラーのタイプを取得し、これが不正な形式の電子メールのエラーコードである場合、正常に失敗する必要があります。
残念ながら、Firebaseで使用されているエラーコードのリストが見つかりませんでした。例外を1回トリガーし、エラーコードとそれに応じてコードを書き留めます。
Firebase authにはいくつかの例外があります。 @kingspeechに加えて
((FirebaseAuthException)task.getException()).getErrorCode()
を使用してエラーのタイプを取得し、次のようにswitch
で処理する必要があります。
private void loginUser(String email, String password) {
mAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
startActivity(new Intent(MainActivity.this, Main2Activity.class));
} else {
String errorCode = ((FirebaseAuthException) task.getException()).getErrorCode();
switch (errorCode) {
case "ERROR_INVALID_CUSTOM_TOKEN":
Toast.makeText(MainActivity.this, "The custom token format is incorrect. Please check the documentation.", Toast.LENGTH_LONG).show();
break;
case "ERROR_CUSTOM_TOKEN_MISMATCH":
Toast.makeText(MainActivity.this, "The custom token corresponds to a different audience.", Toast.LENGTH_LONG).show();
break;
case "ERROR_INVALID_CREDENTIAL":
Toast.makeText(MainActivity.this, "The supplied auth credential is malformed or has expired.", Toast.LENGTH_LONG).show();
break;
case "ERROR_INVALID_EMAIL":
Toast.makeText(MainActivity.this, "The email address is badly formatted.", Toast.LENGTH_LONG).show();
etEmail.setError("The email address is badly formatted.");
etEmail.requestFocus();
break;
case "ERROR_WRONG_PASSWORD":
Toast.makeText(MainActivity.this, "The password is invalid or the user does not have a password.", Toast.LENGTH_LONG).show();
etPassword.setError("password is incorrect ");
etPassword.requestFocus();
etPassword.setText("");
break;
case "ERROR_USER_MISMATCH":
Toast.makeText(MainActivity.this, "The supplied credentials do not correspond to the previously signed in user.", Toast.LENGTH_LONG).show();
break;
case "ERROR_REQUIRES_RECENT_LOGIN":
Toast.makeText(MainActivity.this, "This operation is sensitive and requires recent authentication. Log in again before retrying this request.", Toast.LENGTH_LONG).show();
break;
case "ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL":
Toast.makeText(MainActivity.this, "An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address.", Toast.LENGTH_LONG).show();
break;
case "ERROR_EMAIL_ALREADY_IN_USE":
Toast.makeText(MainActivity.this, "The email address is already in use by another account. ", Toast.LENGTH_LONG).show();
etEmail.setError("The email address is already in use by another account.");
etEmail.requestFocus();
break;
case "ERROR_CREDENTIAL_ALREADY_IN_USE":
Toast.makeText(MainActivity.this, "This credential is already associated with a different user account.", Toast.LENGTH_LONG).show();
break;
case "ERROR_USER_DISABLED":
Toast.makeText(MainActivity.this, "The user account has been disabled by an administrator.", Toast.LENGTH_LONG).show();
break;
case "ERROR_USER_TOKEN_EXPIRED":
Toast.makeText(MainActivity.this, "The user\\'s credential is no longer valid. The user must sign in again.", Toast.LENGTH_LONG).show();
break;
case "ERROR_USER_NOT_FOUND":
Toast.makeText(MainActivity.this, "There is no user record corresponding to this identifier. The user may have been deleted.", Toast.LENGTH_LONG).show();
break;
case "ERROR_INVALID_USER_TOKEN":
Toast.makeText(MainActivity.this, "The user\\'s credential is no longer valid. The user must sign in again.", Toast.LENGTH_LONG).show();
break;
case "ERROR_OPERATION_NOT_ALLOWED":
Toast.makeText(MainActivity.this, "This operation is not allowed. You must enable this service in the console.", Toast.LENGTH_LONG).show();
break;
case "ERROR_WEAK_PASSWORD":
Toast.makeText(MainActivity.this, "The given password is invalid.", Toast.LENGTH_LONG).show();
etPassword.setError("The password is invalid it must 6 characters at least");
etPassword.requestFocus();
break;
}
}
}
});
}
ユーザーにメッセージを表示するだけの場合、これは機能します。シンプルでエレガント:
if (!task.isSuccessful()) {
Log.w(TAG, "signInWithEmail:failed", task.getException());
Toast.makeText(LoginActivity.this, "User Authentication Failed: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
.getMessage()メソッドは例外をすでに使用可能なフォーマットに変換しているように見え、ユーザーにそれを表示するだけです。
(これは私の最初のコメントです。建設的な批判をお願いします)
Steve-guidettiまたはpdegand59メソッドを使用できます。 steve-guidettiのメソッドを使用しました(2つの例外がありません)
考えられるすべての例外については、以下を参照してください。
ここで詳しく説明されています。
https://firebase.google.com/docs/reference/js/firebase.auth.Auth
「createUserWithEmailAndPassword」を検索して、
エラーコード
auth/email-already-in-use
Thrown if there already exists an account with the given email address.
auth/invalid-email
Thrown if the email address is not valid.
auth/operation-not-allowed
Thrown if email/password accounts are not enabled. Enable email/password accounts in the Firebase Console, under the Auth tab.
auth/weak-password
Thrown if the password is not strong enough.
5つの例外すべてについて:ここをチェックしてください
https://firebase.google.com/docs/reference/Android/com/google/firebase/auth/FirebaseAuthException
ここでは、5種類のAuthExceptionを見つけることができます。 4つの既知の直接サブクラスと1つの間接サブクラス
Steve-guidettiまたはpdegand59メソッドを使用できます。
ユーザーからクラウドにアップストリームメッセージを送信する場合は、firebaseコールバック関数onMessageSent
およびonSendError
を実装して、アップストリームメッセージのステータスを確認します。エラーの場合、onSendError
は、エラーコードとともにSendExceptionを返します。
たとえば、20メッセージの制限に達した後、クライアントがさらにメッセージを送信しようとすると、SendException#ERROR_TOO_MANY_MESSAGES。を返します。
別のソリューションを試しましたが、気に入らなかった。
これはどうですか:
if (!task.isSuccessful()) {
Exception exc = task.getException();
if (exc.getMessage().contains("The email address is badly formatted.")) {
etUser.setError(getString(R.string.error_wrong_email));
etUser.requestFocus();
}
else
if (exc.getMessage().contains("There is no user record corresponding to this identifier. The user may have been deleted.")) {
etUser.setError(getString(R.string.error_user_not_exist));
etUser.requestFocus();
}
else
if (exc.getMessage().contains("The password is invalid or the user does not have a password")) {
etPass.setError(getString(R.string.error_wrong_password));
etPass.requestFocus();
}
Log.w(TAG, "signInWithEmail:failed", task.getException());
Toast.makeText(AuthActivity.this, R.string.auth_failed,
Toast.LENGTH_SHORT).show();
}
LOGIN_EXCEPTIONS
FirebaseAuthException
-Firebase認証に関連する一般的な例外。詳細については、エラーコードとメッセージを確認してください。
ERROR_USER_DISABLE
D(Firebaseコンソールなどで)ユーザーが無効にされている場合
ERROR_USER_NOT_FOUND
ユーザーが削除されている場合(たとえば、Firebaseコンソール、またはこのアプリの別のインスタンス)
ERROR_USER_TOKEN_EXPIRED
バックエンドでユーザーのトークンが取り消された場合。これは、ユーザーの資格情報が別のデバイスで変更された場合(パスワード変更イベントなど)に自動的に発生します。
ERROR_INVALID_USER_TOKEN
ユーザーのトークンの形式が正しくない場合。これは通常の状況では発生しません。
mAuth.signInWithEmailAndPassword(login, pass)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if(task.isSuccessful())
{
}else if (task.getException() instanceof FirebaseAuthInvalidUserException) {
}else if(((FirebaseAuthException) task.getException()).getErrorCode().equals("ERROR_USER_DISABLED"))
{
}else if(((FirebaseAuthException) task.getException()).getErrorCode().equals("ERROR_USER_NOT_FOUND "))
{
}else if(((FirebaseAuthException) task.getException()).getErrorCode().equals("ERROR_USER_TOKEN_EXPIRED "))
{
}else if(((FirebaseAuthException) task.getException()).getErrorCode().equals("ERROR_INVALID_USER_TOKEN "))
{
}
}
});
REGISTER_EXCEPTIONS
FirebaseAuthEmailException
Firebase Authを介してメールを送信しようとした結果の例外を表します(例:パスワードリセットメール)
FirebaseAuthInvalidCredentialsException
-メソッドに渡された1つまたは複数の資格情報が、その操作のユーザーサブジェクトの識別または認証に失敗した場合にスローされます。エラーコードとメッセージを調べて、特定の原因を見つけてください。
FirebaseAuthWeakPasswordException
-弱いパスワード(6文字未満)を使用して新しいアカウントを作成するか、既存のアカウントのパスワードを更新する場合にスローされます。 getReason()を使用して、検証が失敗した理由を示すメッセージを取得し、ユーザーに表示できます。
これを使用できます:
mAuth.getCurrentUser().linkWithCredential(authCredential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "linkWithCredential:success");
} else {
Log.w(TAG, "linkWithCredential:failure", task.getException());
Toast.makeText(getApplicationContext(), "Authentication failed. " + task.getException().toString, Toast.LENGTH_SHORT).show();
}
// ...
}
});
過去にgetErrorCode()を使用してエラーのタイプを取得し、正常に失敗しました。 APIの新しいバージョンでは、getErrorCode()は推奨されません。代わりにresponse.getError()。getErrorCode()を使用する必要があります
com.firebase.ui.auth.IdpResponse
@Deprecated
public int getErrorCode()
Get the error code for a failed sign in
Deprecated use getError() instead
だから例えば.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
// Successfully signed in
if (resultCode == RESULT_OK) {
//dbHandler = DBMS.getInstance(this);
FirebaseAuth auth = FirebaseAuth.getInstance();
FirebaseUser user = auth.getCurrentUser();
FirebaseUserMetadata metadata = auth.getCurrentUser().getMetadata();
// initialize profile first
if (metadata.getCreationTimestamp() == metadata.getLastSignInTimestamp()) {
//start main activity after profile setup
startActivity(new Intent(this, MainActivity.class));
return;
} else {
// This is an existing user
// show them a welcome back screen.
startActivity(new Intent(this, MainActivity.class));
return;
}
} else {
// Sign in failed
// check response for error code
if (response == null) {
// User pressed back button
showSnackbar(R.string.sign_in_cancelled);
return;
}
if (response.getError().getErrorCode() == ErrorCodes.NO_NETWORK) {
showSnackbar(R.string.no_internet_connection);
return;
}
if (response.getError().getErrorCode() == ErrorCodes.UNKNOWN_ERROR) {
showSnackbar(R.string.unknown_error);
return;
}
}
showSnackbar(R.string.unknown_sign_in_response);
}
}
以下を試してください:
if (task.isSuccessful()) {
//Toast.makeText(getContext(),"Registration successful", Toast.LENGTH_SHORT).show();
try {
Toast.makeText(getContext(),"Registration successful", Toast.LENGTH_SHORT).show();
throw task.getException();
}
// if user enters wrong email.
catch (FirebaseAuthWeakPasswordException weakPassword) {
Log.d("Registration Error", "onComplete: weak_password");
// TODO: take your actions!
}
// if user enters wrong password.
catch (FirebaseAuthInvalidCredentialsException malformedEmail) {
Log.d("Registration Error", "onComplete: malformed_email");
// TODO: Take your action
}
catch (FirebaseAuthUserCollisionException existEmail) {
Log.d("Registration Error", "onComplete: exist_email");
// TODO: Take your action
}
catch (Exception e) {
Log.d("Registration Error", "onComplete: " + e.getMessage());
}
} else {
//Toast.makeText(getContext(), "ERROR, Please try again.", Toast.LENGTH_SHORT).show();
Toast.makeText(getContext(), task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
これは私がKotlinで使用する方法です
fun handleErrorsFirebaseAuth(err:FirebaseAuthException): String {
when (err.errorCode) {
"ERROR_INVALID_EMAIL" -> return "Introduce un email válido"
"ERROR_EMAIL_ALREADY_IN_USE" -> return "Este email ya está en uso , usa otra cuenta o recupera la contraseña"
"ERROR_WEAK_PASSWORD" -> return "La contraseña tiene que ser de mínimo 6 carácteres"
"ERROR_WRONG_PASSWORD" -> return "La contraseña es incorrecta"
"ERROR_USER_DISABLED" -> return "Usuario deshabilitado, has infringido alguna norma"
"ERROR_USER_NOT_FOUND" -> return "No encontramos su cuenta. ¿El email es correcto? , contacte con nosotros mediante instagram @gobarberco"
else -> {
return "Se ha producido un error"
}
}
}
つかいます:
val messageError = handleErrorsFirebaseAuth(task.exception as FirebaseAuthException)
ファイアベースの例外をキャッチするには、.addOnFailureListener
追加後.addOnCompleteListener
このような:
private void login_user(String email, String password) {
mAuth.signInWithEmailAndPassword(email,password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
startActivity(intent);
finish();
}if(!task.isSuccessful()){
// To know The Excepton
//Toast.makeText(LoginActivity.this, ""+task.getException(), Toast.LENGTH_LONG).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if( e instanceof FirebaseAuthInvalidUserException){
Toast.makeText(LoginActivity.this, "This User Not Found , Create A New Account", Toast.LENGTH_SHORT).show();
}
if( e instanceof FirebaseAuthInvalidCredentialsException){
Toast.makeText(LoginActivity.this, "The Password Is Invalid, Please Try Valid Password", Toast.LENGTH_SHORT).show();
}
if(e instanceof FirebaseNetworkException){
Toast.makeText(LoginActivity.this, "Please Check Your Connection", Toast.LENGTH_SHORT).show();
}
}
});
try {
throw task.getException();
} catch(FirebaseAuthException e) {
switch (e.getErrorCode()){
case "ERROR_WEAK_PASSWORD":
Toast.makeText(this, "The given password is invalid.", Toast.LENGTH_SHORT).show();
break;
//and other
}
}