Как поймать особые исключения Firebase Auth
Используя 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();
}
}
});
Ответы
Ответ 1
Вы можете выбросить исключение, возвращенное task.getException
внутри блока try, и уловить каждый тип исключения, который может быть использован методом, который вы используете.
Вот пример из 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());
}
}
Ответ 2
В дополнение к ответу @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\ 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\ 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."));
Ответ 3
Вы должны использовать ((FirebaseAuthException)task.getException()).getErrorCode()
, чтобы получить тип ошибки и с ошибкой изящно, если это код ошибки для плохо отформатированного письма.
К сожалению, я не смог найти список кодов ошибок, используемых Firebase.
Триггерное исключение один раз, обратите внимание на код ошибки и код соответственно.
Ответ 4
Если вы просто хотите отображать сообщение пользователю, это работает. Простой и элегантный:
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() конвертирует исключение в удобный для нас формат, и все, что нам нужно сделать, это показать, что где-то пользователю.
(Это мой первый комментарий, конструктивная критика, пожалуйста)
Ответ 5
Существует ряд исключений, связанных с аутентификацией Firebase. В дополнение к @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\\ 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\\ 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;
}
}
}
});
}
Ответ 6
Если вы отправляете восходящие сообщения от пользователя к облаку, реализуйте функции обратного вызова firebase onMessageSent
и onSendError
для проверки состояния восходящих сообщений. В случае ошибок onSendError
возвращает SendException с кодом ошибки.
Например, если клиент пытается отправить больше сообщений после достижения предела 20 сообщений, он возвращает SendException # ERROR_TOO_MANY_MESSAGES.
Ответ 7
Вы можете использовать метод steve-guidetti или pdegand59. Я использовал метод steve-guidetti (два исключения отсутствуют)
Для всех возможных исключений, пожалуйста, см. ниже.
Это хорошо документировано здесь.
https://firebase.google.com/docs/reference/js/firebase.auth.Auth
Найдите "createUserWithEmailAndPassword" и найдите
Коды ошибок
авториз/электронная почта-уже в использовании
Thrown if there already exists an account with the given email address.
Auth/недействительно-почта
Thrown if the email address is not valid.
авт/операция-не-допускается
Thrown if email/password accounts are not enabled. Enable email/password accounts in the Firebase Console, under the Auth tab.
авториз/слабый пароль
Thrown if the password is not strong enough.
За все пять исключений: проверьте здесь
https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseAuthException
Здесь вы можете найти 5 различных типов AuthException. 4 Известный прямой подкласс и 1 косвенный подкласс
Вы можете использовать метод steve-guidetti или pdegand59.
Ответ 8
Я попробовал другие решения, но им не нравились.
Как насчет этого:
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();
}
Ответ 9
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 (например, пароль reset email)
FirebaseAuthInvalidCredentialsException
- Брошено, когда один или несколько учетных данных, переданных методу, не могут идентифицировать и/или аутентифицировать субъект пользователя этой операции. Проверьте код ошибки и сообщение, чтобы узнать конкретную причину.
FirebaseAuthWeakPasswordException
- Создается при использовании слабого пароля (менее 6 символов) для создания новой учетной записи или для обновления существующего пароля учетной записи. Используйте getReason(), чтобы получить сообщение с причиной неудачной проверки, которую вы можете отобразить для своих пользователей.
Ответ 10
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
}
}
коды ошибок: fooobar.com/questions/295752/...
Ответ 11
Чтобы поймать firebase Исключение легко, добавьте .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();
}
}
});
Ответ 12
В прошлом мы использовали 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);
}
}
Ответ 13
Попробуйте следующее:
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();
}
Ответ 14
Это метод, который я использую в 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)
Ответ 15
Вы можете использовать это:
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();
}
// ...
}
});