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

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

Related

Parse server password reset email error ios

I have a Parse iOS App that I want users to be able to reset their account passwords with. I tried using the standard Parse Password Email Reset Function with this code. But it returned this error, "An appName, publicServerURL, and emailAdapter are required for password reset functionality.". I looked into this, and I found that I might need a MailGun or other email service to host my email resets. Is that true? Or is there another way I can address this error?
PFUser.requestPasswordResetForEmailInBackground(myEmail, block: { (success, error) -> Void in
if error == nil {
print("Password Reset Email Sent")
} else {
print(error)
}
})
// MARK: - FORGOT PASSWORD BUTTON
#IBAction func forgotPasswButt(_ sender: AnyObject) {
let alert = UIAlertController(title: APP_NAME,
message: "Type your email address you used to register.",
preferredStyle: .alert)
let ok = UIAlertAction(title: "Reset password", style: .default, handler: { (action) -> Void in
// TextField (optional))
let textField = alert.textFields!.first!
let txtStr = textField.text!
PFUser.requestPasswordResetForEmail(inBackground: txtStr, block: { (succ, error) in
if error == nil {
self.simpleAlert("You will receive an email shortly with a link to reset your password")
}})
})
// Cancel button
let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { (action) -> Void in })
// Add textField
alert.addTextField { (textField: UITextField) in
textField.keyboardAppearance = .dark
textField.keyboardType = .default
}
alert.addAction(ok)
alert.addAction(cancel)
present(alert, animated: true, completion: nil)
}

Firebase Authorization with Swift 3.0 not working

Since updating to Swift 3.0 even with the correct password I receive the incorrect message. Has anyone had this problem with authorizing users on Firebase?
#IBAction func LoginToAccount(_ sender: AnyObject) {
if let email = emailLogin.text, let password = passwordLogin.text {
FIRAuth.auth()?.signIn(withEmail: email, password: password, completion: {
(user, error) in
if error != nil{
print("Incorrect")
let alert = UIAlertController(title: "Error", message: "Incorrect Email or Password.", preferredStyle: UIAlertControllerStyle.alert)
let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}else{
if error == nil {
self.performSegue(withIdentifier: "AdminSegue", sender: self)
}
}
})
}
}
}
If you could create an email and have problem with sign in then it would be like my case. Just check your keychain accessibility from yourproject.xcodeproject -> Capabilities -> keychain Sharing - > On if it is off.
After some research this is apparently an issue with Simulator 10.0 not allowing Firebase to write values to the keychain. Something they are working on apparently but it doesn't affect app on actual device.
You have to make sure the user has been created initially, because you have to create a user first and then sign in using the created user.
#IBAction func LoginToAccount(_ sender: AnyObject) {
if let email = emailLogin.text, let password = passwordLogin.text {
FIRAuth.auth()!.createUser(withEmail: email, password: password) { user, error in
if error == nil {
FIRAuth.auth()!.signIn(withEmail: email, password: password, , completion: { (user, error) in
if error != nil{
print("Incorrect")
let alert = UIAlertController(title: "Error", message: "Incorrect Email or Password.", preferredStyle: UIAlertControllerStyle.alert)
let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
} else {
if error == nil {
self.performSegue(withIdentifier: "AdminSegue", sender: self)
}
}
})
}
}
}

Handling Errors in New Firebase and Swift

I'm trying to add error handling in creating user button in iOS project using swift and firebase:
Here's the code for the button:
#IBAction func Register(sender: AnyObject) {
if NameTF.text == "" || EmailTF.text == "" || PasswordTF.text == "" || RePasswordTF == "" || PhoneTF.text == "" || CityTF.text == ""
{
let alert = UIAlertController(title: "عذرًا", message:"يجب عليك ملىء كل الحقول المطلوبة", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
} else {
if PasswordTF.text != RePasswordTF.text {
let alert = UIAlertController(title: "عذرًا", message:"كلمتي المرور غير متطابقتين", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
} else {
FIRAuth.auth()?.createUserWithEmail(EmailTF.text!, password: PasswordTF.text!, completion: { user, error in
print(error)
if error != nil {
let errorCode = FIRAuthErrorNameKey
switch errorCode {
case "FIRAuthErrorCodeEmailAlreadyInUse":
let alert = UIAlertController(title: "عذرًا", message:"الإيميل مستخدم", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
case "FIRAuthErrorCodeUserNotFound":
let alert = UIAlertController(title: "عذرًا", message:"المستخدم غير موجود", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
case "FIRAuthErrorCodeInvalidEmail":
let alert = UIAlertController(title: "عذرًا", message:"الإيميل غير صحيح", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
case "FIRAuthErrorCodeNetworkError":
let alert = UIAlertController(title: "عذرًا", message:"خطأ في الاتصال بالانترنت", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
default:
let alert = UIAlertController(title: "عذرًا", message:"خطأ غير معروف", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "نعم", style: .Default) { _ in })
self.presentViewController(alert, animated: true){}
}
} else {
FIRAuth.auth()?.signInWithEmail(self.EmailTF.text!, password: self.PasswordTF.text!, completion: { (user: FIRUser?, error: NSError?) in
if let error = error {
print(error.localizedDescription)
} else {
self.ref.child("UserProfile").child(user!.uid).setValue([
"email": self.EmailTF.text!,
"name" : self.NameTF.text!,
"phone": self.PhoneTF.text!,
"city" : self.CityTF.text!,
])
print("Sucess")
// self.performSegueWithIdentifier("SignUp", sender: nil)
}
})
} //else
})
} //Big else
} //Big Big else
}
}//end of
I'm not sure if the syntax of the errors in switch statement is correct or not!
Because when I tested it in the simulator it always gives me the defualt case which is unknown error!
+
I could not find the syntax in the documentation:
https://firebase.google.com/docs/auth/ios/errors
So, What's the correct syntax to add error handling using new firebase and swift!
I've actually just struggled with this for quite a bit of time and found what the issue was. I've tried the code posted in an answer above and the error.code line gave me an error. It did work with error._code though. In other words, credit for the original answer to Paul with a slight modificaiton. Here's my final code (I will edit it for all errors though):
if let errCode = AuthErrorCode(rawValue: error!._code) {
switch errCode {
case .errorCodeInvalidEmail:
print("invalid email")
case .errorCodeEmailAlreadyInUse:
print("in use")
default:
print("Create User Error: \(error)")
}
}
Updated for Swift 4 + Firebase 4 + UIAlertController
extension AuthErrorCode {
var errorMessage: String {
switch self {
case .emailAlreadyInUse:
return "The email is already in use with another account"
case .userNotFound:
return "Account not found for the specified user. Please check and try again"
case .userDisabled:
return "Your account has been disabled. Please contact support."
case .invalidEmail, .invalidSender, .invalidRecipientEmail:
return "Please enter a valid email"
case .networkError:
return "Network error. Please try again."
case .weakPassword:
return "Your password is too weak. The password must be 6 characters long or more."
case .wrongPassword:
return "Your password is incorrect. Please try again or use 'Forgot password' to reset your password"
default:
return "Unknown error occurred"
}
}
}
extension UIViewController{
func handleError(_ error: Error) {
if let errorCode = AuthErrorCode(rawValue: error._code) {
print(errorCode.errorMessage)
let alert = UIAlertController(title: "Error", message: errorCode.errorMessage, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
}
Usage example:
Auth.auth().signIn(withEmail: email, password: password, completion: { (user, error) in
if error != nil {
print(error!._code)
self.handleError(error!) // use the handleError method
return
}
//successfully logged in the user
})
Even though this has been answered correctly, wanted to share a nice implementation for this we added to our project.
This can be done for other error types as well, but we just needed it for the FIRAuthErrorCodes.
If you extend FIRAuthErrorCode to have a variable errorMessage of type string, you can have your own error messages for the users:
extension FIRAuthErrorCode {
var errorMessage: String {
switch self {
case .errorCodeEmailAlreadyInUse:
return "The email is already in use with another account"
case .errorCodeUserDisabled:
return "Your account has been disabled. Please contact support."
case .errorCodeInvalidEmail, .errorCodeInvalidSender, .errorCodeInvalidRecipientEmail:
return "Please enter a valid email"
case .errorCodeNetworkError:
return "Network error. Please try again."
case .errorCodeWeakPassword:
return "Your password is too weak"
default:
return "Unknown error occurred"
}
}
}
You could customize only some as we have above and group the rest under "Unknown error".
With this extension you can handle an error as shown in Vladimir Romanov's answer:
func handleError(_ error: Error) {
if let errorCode = FIRAuthErrorCode(rawValue: error._code) {
// now you can use the .errorMessage var to get your custom error message
print(errorCode.errorMessage)
}
}
FIRAuthErrorCode is an int enum not a string enum. Do the following:
if let error = error {
switch FIRAuthErrorCode(rawValue: error.code) !{
case .ErrorCodeInvalidEmail:
More info in this answer.
I am using Swift 5 and Firebase 6.4.0 and for me, none of the above really worked. After trying around a bit I came up with this:
Auth.auth().createUser(withEmail: emailTextfield.text!, password: passwordTextfield.text!) { (user, error) in
if error!= nil{
let alert = UIAlertController(title: "Error", message: error!.localizedDescription, preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert,animated: true)
}

How to verify a user's email address on iOS with Firebase?

I'm stuck with email verification with firebase. I've looked around for guidance but no help. After the user verifies his email, my code still prints out the user has not been verified. I'm still trying to get used to the syntax of firebase. Here is my code:
if FIRAuth.auth()?.currentUser!.emailVerified == true{
FIRAuth.auth()?.signInWithEmail(email.text!, password: passsword.text!, completion: {
user, error in
if error != nil{
print("Email/password is wrong or user does not exist")
}else{
print("Successful login.")
}
})
}else{
print("Please verify your email.")
}
here is my code for the sign up section:
let eduEmail = email.text
let endInEdu = eduEmail?.hasSuffix("my.utsa.edu")
if endInEdu == true {
FIRAuth.auth()?.createUserWithEmail(email.text!, password: passsword.text!, completion: {
user, error in
if error != nil{
let alert = UIAlertController(title: "User exists.", message: "Please use another email or sign in.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
print("Email has been used, try a different one")
}else{
FIRAuth.auth()?.currentUser!.sendEmailVerificationWithCompletion({ (error) in
})
let alert = UIAlertController(title: "Account Created", message: "Please verify your email by confirming the sent link.", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
print("This is a college email and user is created")
}
})
}else{
print("This is not a my.utsa.edu email")
}
You checked if the user email was verified even before signing them in.
This is what worked for me.
FIRAuth.auth()?.signInWithEmail(txtUsername.text!, password: txtPassword.text!) {
(user, error) in
if let user = FIRAuth.auth()?.currentUser {
if !user.emailVerified{
let alertVC = UIAlertController(title: "Error", message: "Sorry. Your email address has not yet been verified. Do you want us to send another verification email to \(self.txtUsername.text).", preferredStyle: .Alert)
let alertActionOkay = UIAlertAction(title: "Okay", style: .Default) {
(_) in
user.sendEmailVerificationWithCompletion(nil)
}
let alertActionCancel = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
alertVC.addAction(alertActionOkay)
alertVC.addAction(alertActionCancel)
self.presentViewController(alertVC, animated: true, completion: nil)
} else {
print ("Email verified. Signing in...")
}
}
}
You are using the coalescing operator after FIRAuth.auth() which means the following method call will return nil when FIRAuth.auth() was nil. If this is the case, your comparison with true will fail, since nil is not true.
I suggest you to refactor your code like this for easier debugging:
guard let auth = FIRAuth.auth(), user = auth.currentUser else {
print("No auth / user")
}
guard user.emailVerified else {
print("Email not verified")
return
}
guard let email = email.text, password = passsword.text else {
print("No email or password")
return
}
auth.signInWithEmail(email, password: password) { user, error in
if let error = error {
print("Email/password is wrong or user does not exist, error: \(error)")
} else {
print("Successful login.")
}
}
You should find your error easier like this.

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