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)
}
Related
I have a register page with 3 UITextFields and a register button. When the button is clicked, the account is supposed to be registered to my Firebase Database. However, whenever I click the button, the SVProgressHUD.showSuccess() appears, but so does an UIAlert saying "the email address is already in use by another account" in addition to the preformSegue not occurring. This error cannot be true though because none of the emails I am using are registered to my app.
Below is the code I currently am using:
func register() {
Auth.auth().createUser(withEmail: registerEmail.text!, password: registerPassword.text!) { (user, error) in
if error == nil {
SVProgressHUD.dismiss()
SVProgressHUD.showSuccess(withStatus: "Welcome \(self.registerEmail.text!)")
self.performSegue(withIdentifier: "goToTheHome", sender: self)
}
else {
SVProgressHUD.dismiss()
print(error as Any)
print("")
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) }
}
}
#IBAction func createAccount(_ sender: UIButton) {
SVProgressHUD.show()
if registerPassword.text == confirmPassword.text {
register()
}
else {
SVProgressHUD.dismiss()
let alert = UIAlertController(title: "Error", message: "Passwords do not match", preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert,animated: true)
}
}
If the new account was successfully created, the user is signed in, and you can get the user's account data from the result object that's passed to the callback method.
You can try to check your user (result) object in the console..
I'm currently developing an app that has a login page with a login button and main menu button. I've created everything and is working pretty well for the time being. I'm using Firebase as my backend database.
I wanted to create a 'forgot password' button which i already did and seems like its working but the only problem is it doesn't give me an alert when it sends the email, it just sends it, but i get the alert when i enter an email which is not in the user authentication. Below is my code for the forget password button:
#IBAction func frgtpassTapped(_ sender: Any) {
Auth.auth().sendPasswordReset(withEmail: emailTextField.text!) { error in
if self.emailTextField.text?.isEmpty==true{
let resetFailedAlert = UIAlertController(title: "Reset Failed", message: "Error: \(String(describing: error?.localizedDescription))", preferredStyle: .alert)
resetFailedAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(resetFailedAlert, animated: true, completion: nil)
}
if error != nil && self.emailTextField.text?.isEmpty==false{
let resetEmailAlertSent = UIAlertController(title: "Reset Email Sent", message: "Reset email has been sent to your login email, please follow the instructions in the mail to reset your password", preferredStyle: .alert)
resetEmailAlertSent.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(resetEmailAlertSent, animated: true, completion: nil)
}
}
}
I accept if anyone downvotes this post but please if you do, comment below the reason. Any help would be much appreciated!
Please this code
Auth.auth().sendPasswordReset(withEmail: emailTextField.text!) { error in
DispatchQueue.main.async {
if self.emailTextField.text?.isEmpty==true || error != nil {
let resetFailedAlert = UIAlertController(title: "Reset Failed", message: "Error: \(String(describing: error?.localizedDescription))", preferredStyle: .alert)
resetFailedAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(resetFailedAlert, animated: true, completion: nil)
}
if error == nil && self.emailTextField.text?.isEmpty==false{
let resetEmailAlertSent = UIAlertController(title: "Reset Email Sent", message: "Reset email has been sent to your login email, please follow the instructions in the mail to reset your password", preferredStyle: .alert)
resetEmailAlertSent.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(resetEmailAlertSent, animated: true, completion: nil)
}
}
}
It is clear from your code, that you are passing the unWrapped value to the closure, so the textField must contains some value in it.
THIS LINE IN YOUR CODE: if self.emailTextField.text?.isEmpty==true {
will never be entered inside condition.
It should be updated to like:
#IBAction func frgtpassTapped(_ sender: Any) {
//BEFORE SENDING DATA FOR AUTHENTICATION, CHECK FOR THE isEmpty CONDITIONS HERE
Auth.auth().sendPasswordReset(withEmail: emailTextField.text!) { error in
DispatchQueue.main.async {
if error != nil {
// YOUR ERROR CODE
} else {
//YOUR SUCCESS MESSAGE
}
}
}
}
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)
}
}
})
}
}
}
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.
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