Yardi
Yardi

Reputation: 473

Swift Firebase Authentication - two questions about error handling (I'm not sure how to name these errors)

It's really hard to find a proper title for this question. Please be easy on me. The first part is a check to see if an account exists:

Auth.auth().fetchSignInMethods(forEmail: userEmail, completion: {
            (providers, error) in

            if error != nil {
                self.displayAlertMessage(alertTitle: "Unhandled error", alertMessage: "Undefined error #SignUpViewController_0001");
                return;
            } else if providers != nil {
                self.displayAlertMessage(alertTitle: "Error", alertMessage: "This account is not exist.");
                return;
            }
        })

As you can see, I have something named Unhandled error with message Undefined error. I don't know how to name it properly. Can somebody explain that part to me?

The second one is about getting a localized string - any ideas to make it fancy?

Auth.auth().createUser(withEmail: userEmail, password: userPassword) { user, error in if error == nil && user != nil {
            self.displayAlertMessage(alertTitle: "Success", alertMessage: "Your account created successfully. We send you a verification email.", dismiss: true);
            } else {
            self.displayAlertMessage(alertTitle: "Firebase error", alertMessage: "(error!.localizedDescription)");
            }
        }

Thanks for tips :)

Upvotes: 3

Views: 771

Answers (1)

Rob
Rob

Reputation: 2164

You can handle the Errors this way:

 Auth.auth().fetchSignInMethods(forEmail: email, completion: { (response, error) in

        if let error = error, let errCode = AuthErrorCode(rawValue: error._code)
        {
            switch errCode {
            case .emailAlreadyInUse:
                GeneralHelper.sharedInstance.displayAlertMessage(titleStr: LocalizeConstant.CommonTitles.Alert.rawValue.localizedStr(), messageStr: LocalizeConstant.CommonTitles.Continue.rawValue.localizedStr())
            case .accountExistsWithDifferentCredential:
                GeneralHelper.sharedInstance.displayAlertMessage(titleStr: LocalizeConstant.CommonTitles.Alert.rawValue.localizedStr(), messageStr: LocalizeConstant.CommonTitles.Continue.rawValue.localizedStr())
            default:
                break
            }

            return
        }
}

Here I am getting the errCode using AuthErrorCode provided by Firebase itself and then, I am passing in the received error code using error._code. So, now I can get the type of AuthErrorCode. Using this I am making cases like .emailAlreadyInUser, .accountExistsWithDifferentCredential etc. You can just type . and it will show you all the AuthErrorCodes. So, you can simply handle the error codes in this way.

Now, coming to the second part of the question, i.e. getting localized string. You can add localization to Firebase, for that you have to select the language code. Auth.auth().languageCode = "en" //For English. But, I do not think that it gives localized errors as there are many more languages than what Firebase supports. This mainly for sending localized emails.

To handle the localization, you have to create your own method as I did. You can see that I have called a function displayAlertMessage in which I am passing thetitleStr: LocalizeConstant.CommonTitles.Alert.rawValue.localizedStr(), which is a part of localization.

struct LocalizeConstant {

   enum CommonTitles: String
   {
    case Alert = "common_alert"
   }

}

This value designates to the key given by me in the localization file. If you do not know about localization, you have to do a Google search on it. Let's say I have two Localizable.strings one is in English and the other one is in French. In Localizable.strings(English), I've written Alert like this:

"common_alert" = "Alert";

And, In French:

"common_alert" = "Alerte!";

So, this is how I have manually added localization in my app. But, to achieve this you have to do two things. 1) You have to set up your appLanguage. 2) You have to call a method which will fetch the values from these keys defined in the Localizable.strings file.

To do this, I have created a method localizedStr(). It is an extension to String and you can use it as follows.

extension String{
  func localizedStr() -> String
  {
    var finalRes = ""

    if let path = Bundle.main.path(forResource: Constants.appLang, ofType: "lproj") //Constants.appLang is "en" here for "English", but you can set accordingly.
    {
        if let bundle = Bundle(path: path)
        {
            finalRes = NSLocalizedString(self, tableName: nil, bundle: bundle, value: " ", comment: " ")
        }
    }

    return finalRes
 }
}

Now, this method localizedStr() will give you a localized string according to your app language. Even, if Firebase provides localized error codes(which I think it does not), it is impossible to get the error description in each language. So this is the best way I came up with. It may not be the best method out there in the world, but it does the task.

P.S.: To optimize this throughout the app, either you can create an extension to AuthErrorCode or you can create a Helper function where you will just pass the error._code and it will return the localized string. I've added the long way so that you can understand everything in the best way.

Upvotes: 2

Related Questions