3

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 :)

donjuedo
  • 2,475
  • 18
  • 28
Yardi
  • 413
  • 1
  • 5
  • 20
  • Hey! If I'm understanding you right, the first part is asking what to put as the alert? It looks like it's alerting that the user hasn't logged in properly. I usually keep it fairly vague (they can reach out if they still experience issues), so saying "Login not valid" could work! – Kasey Jan 29 '20 at 17:07
  • What do you mean by "make it fancy"? Can you go into more detail on what you want to do? – Kasey Jan 29 '20 at 17:08
  • @Kasey Just want to show simple information what happend :) – Yardi Jan 29 '20 at 17:32
  • Ah okay. It looks like it already does this with "(error!.localizedDescription)" — this should be telling the user the exact issue. If you want an alert for yourself, I would say looking in the console / debugger or Xcode or signing up for Firebase's Crashlytics will do the trick. – Kasey Jan 29 '20 at 18:50
  • Hi, It looks like you are not sure about error messages? Is it right or I misunderstood your question? – Negar Moshtaghi Jan 31 '20 at 12:32
  • If you want happy users, errors should be handled by reporting 1) what failed, 2) why it failed, and 3) what the user should do about it. Following this guideline, it's much harder for a user to get stuck, puzzled, or frustrated. – donjuedo Feb 05 '20 at 12:42

1 Answers1

2

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.

Rob
  • 2,086
  • 18
  • 25