2016-06-16 103 views
20

使用Firebase時,如何捕獲特定的例外並優雅地告知用戶?例如:如何捕獲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(); 
     } 
    }  
}); 

回答

52

您可以通過拋出一個task.getException try塊內返回的異常和捕獲異常的每種類型的可以由所使用的方法可能拋出。

以下是createUserWithEmailAndPassword方法的OnCompleteListener的示例。

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

我有這個問題。 Firebase只會向我返回一個FirebaseException,而不是FirebaseAuthWeakPasswordException或其他。但該消息似乎很好:「WEAK_PASSWORD」。任何想法 ? – Cocorico

+0

您可以在最後的'catch'塊中查看沒有特定類型的異常。 –

+0

是的,我明白了。但是,爲什麼你有FirebaseAuthWeakPasswordException,我不能?如果我使用msg類型進行切換,那麼它就是錯誤的代碼,因爲我應該可以使用類類型正確執行它。 – Cocorico

6

您應該使用((FirebaseAuthException)task.getException()).getErrorCode()得到錯誤的類型和正常失敗,如果這是一個壞格式的電子郵件的錯誤代碼。

不幸的是,我找不到Firebase使用的錯誤代碼列表。 觸發一次異常,相應地記下錯誤代碼和代碼。

+0

task.getException()不能總是被轉換爲FirebaseAuthException,例如當沒有網絡連接時。在這種情況下,異常是FirebaseNetworkException – DavidH

+0

@DavidH如果您使用task.getException()不爲空,它將解決該問題 – mehmet

2

如果您要將上游消息從用戶發送到雲,請實施Firebase回調函數onMessageSentonSendError以檢查上游消息的狀態。在錯誤情況下,onSendError返回一個SendException帶有錯誤代碼。

例如,如果客戶端在達到20條消息限制後嘗試發送更多消息,則返回SendException#ERROR_TOO_MANY_MESSAGES。

20

除了@ 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.")); 
2

您可以使用steve-guidetti或pdegand59方法。我使用了steve-guidetti的方法(缺少兩個例外)

對於所有可能的例外情況,請在下面找到ref。

這裏有很好的文檔。

https://firebase.google.com/docs/reference/js/firebase.auth.Auth

搜索 「createUserWithEmailAndPassword」,並找到

錯誤代碼

AUTH /電子郵件已經在使用

Thrown if there already exists an account with the given email address. 

認證/無效的電子郵件

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. 

AUTH /弱密碼

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方法。

+0

這實際上並不回答他的問題。 – alzee

+1

這是針對Auth特定權限,缺少兩個例外。檢查參考 – Itzdsp

+2

他問「我如何捕獲特定的異常並優雅地告訴用戶」,而不是「給我一個可能的例外列表」。你的回答對這些事情都沒有幫助 - 如何捕捉異常,或者如何通知用戶。 – alzee

2

我嘗試了另一種解決方案,但不喜歡它們。

這個怎麼樣:

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

如果你只是想顯示一條消息,該工作時用戶。簡單和優雅:

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()方法例外成可用的格式轉換爲我們已經和所有我們所要做的就是顯示器在某處給用戶。

(這是我的第一個評論,建設性的批評意見請)

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

錯誤代碼:https://stackoverflow.com/a/38244409/2425851

0

搭上火力異常很容易,你應該添加.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(); 
      } 
     } 
    }); 
+0

Isn'這有點麻煩嗎?與其他方法相比。 – Taslim

0

LOGIN_EXCEPTIONS

FirebaseAuthException - 與Firebase身份驗證相關的一般異常。查看錯誤代碼和消息以獲取更多詳細信息。

ERROR_USER_DISABLE d如果如果用戶已被刪除的用戶已被禁用(例如,在火力地堡控制檯)

ERROR_USER_NOT_FOUND(例如,在火力地堡控制檯,或在此應用的另一實例)

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 

代表的例外,這是企圖通過火力地堡驗證(例如,密碼重置電子郵件)發送電子郵件的結果

FirebaseAuthInvalidCredentialsException - 當一個拋出該異常或更多傳遞給方法的憑證無法識別和/或認證該操作的用戶主體。檢查錯誤代碼和消息以找出具體原因。

FirebaseAuthWeakPasswordException - 使用弱密碼(少於6個字符)創建新帳戶或更新現有帳戶密碼時引發。使用getReason()獲取消息,其中包含驗證失敗的原因,您可以向用戶顯示該消息。

2

除了@kingspeech 您應該使用((FirebaseAuthException)task.getException()).getErrorCode()得到錯誤的類型,然後在開關的情況下這樣的處理:

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