Search code examples
swiftfirebasegoogle-cloud-firestorefirebase-authenticationuialertcontroller

Getting an error trying to reauthenticate user with Firebase


So my goal is to have a user be re-authenticated and then be able to update their password after. So right now I have an alert controller that is presented when a cell is tapped, and in that alert is textFields for re-authentication.

        var reauthEmailTextField = UITextField()
        var reauthPasswordTextField = UITextField()
        let credential: AuthCredential = EmailAuthProvider.credential(withEmail: reauthEmailTextField.text ?? "", password: reauthPasswordTextField.text ?? "")
        let reauthAlert = UIAlertController(title: "Reauthenticate", message: "In order for you to change your password, you must provide your sign-in credentials again.", preferredStyle: .alert)
        let submit = UIAlertAction(title: "Submit", style: .default) { (sub) in
            user.reauthenticate(with: credential) { (result, error) in
                guard error == nil else {
                    print("The user couldn't be reauthenticated. Email: \(reauthEmailTextField.text ?? "") Password:  \(reauthPasswordTextField.text ?? "")")
                    return
                } ...



     reauthAlert.addTextField { (reAuthEmail) in
            reauthEmailTextField = reAuthEmail
            reAuthEmail.placeholder = "Your Email"
            reAuthEmail.clearButtonMode = .whileEditing
        }
        
        reauthAlert.addTextField { (reAuthPass) in
            reauthPasswordTextField = reAuthPass
            reAuthPass.clearButtonMode = .whileEditing
            reAuthPass.placeholder = "Your Password"
            reAuthPass.isSecureTextEntry = true
        }
        
        reauthAlert.addAction(UIAlertAction(title: "Dismiss", style: .cancel))
        reauthAlert.addAction(submit)
        
        present(reauthAlert, animated: true, completion: nil)

Now when the user is successfully re-authenticated it would dismiss the current alert and present a new alert to actually update the user password. The issue is, the re-authentication process always fails and never ends up presenting the second alert. The print statement does print out the input in the textFields, so I know it's nothing to do with the textFields. I was reading through a couple of posts about re-authentication and was comparing my code with the others and I'm confident that I got the syntax down correct so I just really can't understand the issue with this re-authentication not working. Any suggestions?


Solution

  • You're creating your credential object before the user has a chance to enter anything into the text fields:

    var reauthEmailTextField = UITextField()
    var reauthPasswordTextField = UITextField()
    let credential: AuthCredential = EmailAuthProvider.credential(withEmail: reauthEmailTextField.text ?? "", password: reauthPasswordTextField.text ?? "") //<-- Here
    

    In this scenario, you'll always get "" for both values.

    Instead, you need to capture these values inside your submit closure:

    let submit = UIAlertAction(title: "Submit", style: .default) { (sub) in
    
       //get text field values and build `credential` object here
       let credential: AuthCredential = EmailAuthProvider.credential(withEmail: reauthEmailTextField.text ?? "", password: reauthPasswordTextField.text ?? "")
    
       user.reauthenticate(with: credential) { (result, error) in
                    guard error == nil else {
                        print("The user couldn't be reauthenticated. Email: \(reauthEmailTextField.text ?? "") Password:  \(reauthPasswordTextField.text ?? "")")
                        return
                    } ...