Handling Email Does not Exist Error - iOS project using swift - ios

Here's my ResetPassword Button for my iOS application using xcode and swift:
//ResetPssword Button
#IBAction func ResetPassword(sender: AnyObject) {
if validateEmail(EmailTextField.text!) == false {
print("Enter a Valid Email Address")
let VaildMessage = "Enter an Email Address"
//Empty TextField Alert Message
self.disaplayErrorMessage(VaildMessage)
}
//Reset
else {
ref.resetPasswordForUser(EmailTextField.text) { (ErrorType) -> Void in
if ErrorType != nil {
let error = ErrorType
print("There was an error processing the request \(error.description)")
let errorMessage:String = "The Email You Entered is not Exist"
//Error Alert Message
self.disaplayErrorMessage(errorMessage)
} else {
print("Password Reset Sent Successfully")
if let Email = self.EmailTextField.text {
let successMessage = "Email Message was Sent to You at \(Email)"
//Success Alert Message
self.disaplayErrorMessage(successMessage) }
}
} //reset
} //Big Else
} //Button
//Display Alert Message With Confirmation
func disaplayErrorMessage(theMessage:String)
{
//Display alert message with confirmation.
let myAlert = UIAlertController(title: "Alert", message: theMessage, preferredStyle: UIAlertControllerStyle.Alert);
let OkAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default) {
action in
self.dismissViewControllerAnimated(true, completion: nil);
}
myAlert.addAction(OkAction);
self.presentViewController(myAlert, animated: true, completion: nil)
}
//Validate Email Function
func validateEmail(candidate: String) -> Bool {
let emailRegex = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
return NSPredicate(format: "SELF MATCHES %#", emailRegex).evaluateWithObject(candidate)
}
I want to make an error that gives the user an alert when email does not exist in the firebase.
I did not know how to do that.
What I did, I gave the user an alert when error != nil
Is that the right way to do it?

The firebase website has a full listing of error codes
User Authentication
The pre-defined error codes provide info on pretty much all of the errors you may receive when authenticating or handling users.
ref.resetPassword({
email: EmailTextField.text!
}, function(error) {
if (error != nil) {
if let errorCode = FAuthenticationError(rawValue: error.code) {
switch (errorCode) {
case .UserDoesNotExist:
println("Handle invalid user")
case .InvalidEmail:
println("Handle invalid email")
case .InvalidPassword:
println("Handle invalid password")
default:
println("Handle default situation")
}
}
} else {
// Success!
}
}

According to FireBase doc here it may not always be a case. Don't put it as ErrorType, change it to error. It will be NSError type. Check code of the error you get like so:
if error != nil {
if error.description == "INVALID_USER" {
// show alert that user doesn't exists
} else {
// something went wrong
}
}
}

Related

Alert controller not being presented even though condition is met (value is empty)

I've been having an issue with a personal app where certain users seem to be missing a profile picture when they sign up (String). I've added a check to make sure the string isn't empty when the user presses the "Next" button - basically check if the string is "", and if so, present an alert controller to remind them to choose a profile picture. If it's not empty, then segue to the next screen. This is the relevant code (for clarity, var emailUserPicString = "" is a global variable):
emailUserPicString = url.absoluteString
print("\n\n\npic:\(emailUserPicString)\n\n\n")
if emailUserPicString == "" {
let alertController = UIAlertController(title: "Profile Picture Error", message: "Don't forget to choose a profile picture!", preferredStyle: UIAlertControllerStyle.alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {(alert :UIAlertAction!) in
})
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
return
} else {
self.performSegue(withIdentifier: "emailToSetup", sender: nil)
}
Now, when I test this solution, pressing the Next button doesn't do anything, and no alert is presented. I'd think it would be one or the other - if the string is empty, the alert controller would be shown, and if there's a value, performSegue would happen and we'd be taken to the next screen. I'm wondering why neither of these are happening
This is the complete function if it can provide some context:
#IBAction func emailSignupNextPressed(_ sender: Any) {
// Make sure text fields aren't empty
guard nameField.text != "", emailField.text != "", passwordField.text != "", confirmPasswordField.text != "" else {return}
if passwordField.text == confirmPasswordField.text {
Auth.auth().createUser(withEmail: emailField.text!, password: passwordField.text!, completion: { (user, error) in
if let error = error {
print(error.localizedDescription)
}
if let user = user {
guard let uid = Auth.auth().currentUser?.uid else {return}
// Use name as Firebase display name for readability
let changeRequest = Auth.auth().currentUser!.createProfileChangeRequest()
changeRequest.displayName = self.nameField.text!
changeRequest.commitChanges(completion: nil)
// Create child node from userStorage "users". Profile image set to user's unique ID
let imageRef = self.userStorage.child("\(uid).jpg")
let data = UIImageJPEGRepresentation(self.selectProfileImageView.image!, 0.5)
// Upload image to Firebase
let uploadTask = imageRef.putData(data!, metadata: nil, completion: { (metadata, err) in
if err != nil {
print(err!.localizedDescription)
}
imageRef.downloadURL(completion: { (url, er) in
if er != nil {
print(er?.localizedDescription as Any)
}
if let url = url {
emailUserPicString = url.absoluteString
print("\n\n\npic:\(emailUserPicString)\n\n\n")
if emailUserPicString == "" {
let alertController = UIAlertController(title: "Profile Picture Error", message: "Don't forget to choose a profile picture!", preferredStyle: UIAlertControllerStyle.alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: {(alert :UIAlertAction!) in
})
alertController.addAction(okAction)
self.present(alertController, animated: true, completion: nil)
return
} else {
self.performSegue(withIdentifier: "emailToSetup", sender: nil)
}
}
})
})
uploadTask.resume()
}
})
} else {
// print("Passwords don't match")
passwordAlert()
}
}
My question is, am I handling the string check correctly? If there's no value there, why is my alert controller not presenting? And if there is a value why is the segue not being performed?
As I can see, you are presenting the UIAlertAction in a background Thread. So, you should present it in the UI Thread using:
DispatchQueue.main.async {
// show alert here
}
try to change your if statement to
if emailUserPicString.isEmpty || emailUserPicString.isEmpty == ""{
}
Maybe an empty textField don't has a == "" String
Follow this solution:
private func validateForm() {
if emailTextField.text?.isEmpty {
// Show alert message like: Please enter the email addess.
return
}
if passwordTextField.text?.isEmpty && passwordTextField.text?.count < 6 {
// Show alert message like: Password must be at least 6 chars long.
return
}
if profleImage.image == nil {
// Show alert message like: Please choose your profile photo.
return
}
// Now you can post API request after validating all values.
// Call here API request method.....
}

How to catch ERROR_EMAIL_ALREADY_IN_USE in FirebaseAuth in Swift?

I'm trying to authenticate new users and storing their email and password into FirebaseAuth using the following code:
Auth.auth().createUser(withEmail: email, password: password) { (user, error) in
if user == nil || error != nil {
let alert = UIAlertController(title: "Please Try Again",
message: "Invalid email or password",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default) {_ in })
self.present(alert, animated: true)
}
else {
self.performSegue(withIdentifier: "nextpage", sender: self)
}
}
However, I'm running into a problem, which is that when a user enters an email is already in use, FirebaseAuth doesn't return an error; instead, it simply overrides the current email. I read in the documentation that an error called ERROR_EMAIL_ALREADY_IN_USE can be thrown as part of FirebaseAuthUserCollisionException, how can this be caught? Thanks!
Place this code in the callback handler:
if let error = error {
switch FIRAuthErrorCode(rawValue: error!._code) {
case .emailAlreadyInUse:
print("Email already in use")
default:
print("Other error")
}
}
Now you can remove the if user == nil || error != nil if block.
Also see https://firebase.google.com/docs/reference/ios/firebaseauth/api/reference/Enums/FIRAuthErrorCode for a list of error codes.
April 2019
{ (error) in
switch AuthErrorCode(rawValue: error._code) {
case .emailAlreadyInUse?:
print("Email is already in use")
default:
print("Other error types.")
}
}

Firebase Authentication:Newly created user can't be saved in Firebase

I was registering users with Firebase, but newly created user can't be saved in Firebase though I've refreshed the Firebase Login & Auth tab.Could you help me fix it?
The code is here:
let saveAction = UIAlertAction(title: "Save", style: .Default) { (action:UIAlertAction) in
self.ref.createUser(self.textFieldLoginEmail.text, password: self.textFieldLoginPassword.text, withCompletionBlock: { (error:NSError!) in
if error == nil
{
self.ref.authUser(self.textFieldLoginEmail.text, password: self.textFieldLoginPassword.text, withCompletionBlock: { (error, auth) -> Void in
})
}
})
}
Try an figure out what is the error is when you try and log in, here an example for the use of the Firebase error log:
Data.ref.authUser(textFieldLoginEmail.text, password: textFieldLoginPassword.text, withCompletionBlock: { error, authData in
if error != nil {
var msg = ""
if let errorCode = FAuthenticationError(rawValue: error.code) {
switch (errorCode) {
case .UserDoesNotExist:
msg = "Invalid user name"
case .InvalidEmail:
msg = "Invalid email"
case .InvalidPassword:
msg = "Invalid password"
case .NetworkError:
msg = "we're sorry, network error has occurred, please login from the settings menu later"
default:
msg = "we're sorry, we encountered an error, please try again"
}
let alert = UIAlertController(title: "User Authentication error",
message: msg,
preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK",
style: .Default) { (action: UIAlertAction!) -> Void in
if errorCode == .NetworkError {
self.performSegueWithIdentifier("ToMenuSegue", sender: self)
}
self.textFieldLoginPassword.text = ""
self.view.endEditing(true)
}
alert.addAction(OKAction)
self.presentViewController(alert, animated: true, completion: nil)
}
} else {
// Logged in
self.performSegueWithIdentifier("ToMenuSegue", sender: self)
}
})
The full Firebase errors list

Optional Text in Alert in ResetPassword - iOS Project using Swift

Here's my ResetPassword Button for my iOS application using xcode and swift:
//ResetPssword Button
#IBAction func ResetPassword(sender: AnyObject) {
if validateEmail(EmailTextField.text!) == false {
print("Enter a Valid Email Address")
let VaildMessage = "Enter an Email Address"
//Empty TextField Alert Message
self.disaplayErrorMessage(VaildMessage)
}
//Reset
else {
ref.resetPasswordForUser(EmailTextField.text) { (ErrorType) -> Void in
if ErrorType != nil {
let error = ErrorType
print("There was an error processing the request \(error.description)")
let errorMessage:String = "The Email You Entered is not Exist"
//Error Alert Message
self.disaplayErrorMessage(errorMessage)
} else {
print("Password Reset Sent Successfully")
let successMessage = "Email Message was Sent to You at \(self.EmailTextField.text)"
//Success Alert Message
self.disaplayErrorMessage(successMessage)
}
} //reset
} //Big Else
} //Button
//Display Alert Message With Confirmation
func disaplayErrorMessage(theMessage:String)
{
//Display alert message with confirmation.
let myAlert = UIAlertController(title: "Alert", message: theMessage, preferredStyle: UIAlertControllerStyle.Alert);
let OkAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default) {
action in
self.dismissViewControllerAnimated(true, completion: nil);
}
myAlert.addAction(OkAction);
self.presentViewController(myAlert, animated: true, completion: nil)
}
//Validate Email Function
func validateEmail(candidate: String) -> Bool {
let emailRegex = "[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
return NSPredicate(format: "SELF MATCHES %#", emailRegex).evaluateWithObject(candidate)
}
If the password reset sent successfully, there will be an alert that prints out the email address. But it prints email with optional word!
How can I print it without the optional word?
You have to unwrap the Optional text field.
For example with if let:
if let text = self.EmailTextField.text {
let successMessage = "Email Message was Sent to You at \(text)"
//Success Alert Message
self.disaplayErrorMessage(successMessage)
}
Did you tried to force unwrap the value using the ! sign ?

Handling certain errors in Parse

I'm looking to create certain events when certain error codes occur in my program. For instance, if there is an error code 200, I need to let the user know they are missing the username field. Or for an error code 125, I need to let them know they did not enter a valid email address when creating for an account. How do I target these error codes specifically? I have tried the code below with no success, what am I doing wrong and is this possible?
if error.code == 125 {
var invalidEmail:UIAlertView = UIAlertView(title: Please try again, message: "That does not look like a real email address. Please enter a real one.", delegate: self, cancelButtonTitle: "Try again")
invalidEmail.show()
}
The error that xCode is telling me is that I have an unresolved identifier 'error'. There is an instance of this in the parse starter project file 'AppDelegate.swift' that calls the following code and it seems to work perfectly fine.
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
if error.code == 3010 {
println("Push notifications are not supported in the iOS Simulator.")
} else {
println("application:didFailToRegisterForRemoteNotificationsWithError: %#", error)
}
}
My code
#IBAction func signupTapped(sender: AnyObject) {
let fullname = fullnameField.text
let email = emailField.text
let username = usernameField.text
let password = passwordField.text
var user = PFUser()
user.username = username
user.password = password
user.email = email
// other fields can be set just like with PFObject
user["fullname"] = fullname
if error.code == 125 {
let alert = UIAlertController(title: "Please try again", message: "That does not look like a valid email address.", preferedStyle: .Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(alert, animated: true)
}
if fullname.isEmpty || email.isEmpty || username.isEmpty || password.isEmpty {
let emptyFieldsError:UIAlertView = UIAlertView(title: "Please try again", message: "Please fill out all the fields so that we can create your account.", delegate: self, cancelButtonTitle: "Try again")
emptyFieldsError.show()
}
user.signUpInBackgroundWithBlock {
(succeeded: Bool, error: NSError?) -> Void in
if let error = error {
let errorString = error.userInfo?["error"] as? NSString
// Show the errorString somewhere and let the user try again.
} else {
// Hooray! Let them use the app now.
}
}
}
There is no error defined where you have your code. You can only reference error from inside a scope in which it exists.
user.signUpInBackgroundWithBlock {
(succeeded: Bool, error: NSError?) -> Void in
if let error = error {
let errorString = error.userInfo?["error"] as? NSString
// PUT YOUR ERROR HANDLING CODE HERE
} else {
}
}
As #Larme already pointed out, UIAlertView is deprecated, so you should use UIAlertController:
if error.code == 125 {
let alert = UIAlertController(title: "Please try again", message: "That does not look like a valid email address.", preferedStyle: .Alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(alert, animated: true)
}

Resources