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)
}
}
})
}
}
}
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..
When the user logs in with correct credentials SVProgressHUD shows and dismisses correctly, and the user segues correctly to the main home screen. However when the password or email is incorrect the SVProgressHUD shows endlessly and no alert is popping up.
#IBAction func signInButton(_ sender: Any) {
self.view.endEditing(true)
let email = emailText.text!.lowercased()
let finalEmail = email.trimmingCharacters(in: .whitespacesAndNewlines)
let password = passwordText.text!
if finalEmail.isEmpty || password.isEmpty {
let alertController = UIAlertController(title: "Error!", message: "Please fill in all the fields.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
present(alertController, animated: true, completion: nil)
}else {
SVProgressHUD.show()
Auth.auth().signIn(withEmail: email, password: password) { (user, error) in
if error == nil {
if let user = user {
print("\(user.displayName!) has been signed in")
SVProgressHUD.dismiss()
// self.enter()
self.performSegue(withIdentifier: "signInHome", sender: nil)
}else{
SVProgressHUD.dismiss()
print("error")
let alertController = UIAlertController(title: "Low Blow!", message: "incorrect credentials", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
self.present(alertController, animated: true, completion: nil)
print(error?.localizedDescription as Any)
}
}
}
}
}
in case error is null you forget to dismiss the SVProgressHUD
checkout this code
#IBAction func signInButton(_ sender: Any)
{
self.view.endEditing(true)
let email = emailText.text!.lowercased()
let finalEmail = email.trimmingCharacters(in: .whitespacesAndNewlines)
let password = passwordText.text!
if finalEmail.isEmpty || password.isEmpty
{
let alertController = UIAlertController(title: "Error!", message: "Please fill in all the fields.", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
present(alertController, animated: true, completion: nil)
}
else
{
SVProgressHUD.show()
Auth.auth().signIn(withEmail: email, password: password)
{
(user, error) in
if error == nil
{
if let user = user
{
print("\(user.displayName!) has been signed in")
SVProgressHUD.dismiss()
self.performSegue(withIdentifier: "signInHome", sender: nil)
}
else
{
SVProgressHUD.dismiss()
print("error")
let alertController = UIAlertController(title: "Low Blow!", message: "incorrect credentials", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
self.present(alertController, animated: true, completion: nil)
print(error?.localizedDescription as Any)
}
}
else
{
SVProgressHUD.dismiss()
}
}
}
}
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)
}
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 want to segue to a different view when the user login is successful.
#IBAction func loginAction(sender: UIButton) {
let email = self.email.text
let password = self.password.text
if (email != "" && password != "") { //check that password and email are entered
BASE_REF.authUser(email, password: password, withCompletionBlock: { (error, authData) -> Void in
if (error != nil) { //check if login was successful
print(error)
} else {
NSUserDefaults.standardUserDefaults().setValue(authData.uid, forKey: "uid")
print ("Logged in :)")
self.performSegueWithIdentifier("loginSuccessful", sender: nil)
self.logoutButton.hidden = false
}
})
} else { //otherwise, return error and show alert
let alert = UIAlertController(title: "Error", message: "Enter Email and Password", preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: .Default, handler: nil)
alert.addAction(action)
self.presentViewController(alert, animated: true, completion: nil)
}
}
The segue lies in the else block. The if block checks if there was an error in logging the user in and prints an error if there was. The error is printing when an incorrect ID is passed in, however, the app still segues anyway.
Why is this happening and how can I prevent it!
Thanks?
FIXED: The problem was that my segue was between the button and the ViewController instead of between 2 ViewControllers.
Recreating the segue between the two ViewControllers solved the problem.
Credits to Arun Gupta and Rahul Katariya