Learn Courses My Dashboard

Firebase Authentification

When I go to create a tester account in the virtual phone simulator, I get the error that my password is not valid even though it is. Does anyone see the issue with my code?


Why is your isPasswordValid function defined inside of the validateFields function?

I don’t think that’s the issue though, also you should change the text field to know it’s a password, so then dots will show up, rather than the actual string password

That was how Chris did it in the tutorial. But even If I change it, it is still not fixing the problem.

Does anyone else see a different problem that might be the issue? I have been stuck here.

@JFFerraro5

Joseph,

In your SignUpViewController there appears to be a few inconsistencies.

Can you copy all of your code in your SignUpViewController and paste it in as text in a reply here.

Place 3 back-ticks ``` on the line above your code and 3 back-ticks ``` on the line below your code so that it is formatted nicely in the reply. The 3 back-ticks must be the only characters on the line. The back-tick character is located on the same keyboard key as the tilde character ~ (which is located below the Esc key).

This also makes it easier for anyone assisting as they can copy the code and carry out some testing.

//
//  SignUpViewController.swift


import UIKit

import FirebaseAuth

import Firebase



class SignUpViewController: UIViewController {

    @IBOutlet weak var firstNameTextField: UITextField!
    
    @IBOutlet weak var emailTextField: UITextField!
    
    @IBOutlet weak var passwordTextField: UITextField!
    
    @IBOutlet weak var confirmPasswordTextField: UITextField!
    
    
    
    @IBOutlet weak var signUpButton: UIButton!
    
    @IBOutlet weak var errorLabel: UILabel!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        setUpElements()
    }
        func setUpElements()
        {
            //hide the error label
            errorLabel.alpha=0
        }
        //check fields and validate that data is correct, if everything is correct method returns nil, otherwise returns the error message
    func validateFields() -> String? {
        //check that all fields are filled in
            
        if firstNameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            emailTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            passwordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            confirmPasswordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == ""{
    
                return "Please fill in all fields"
            }
    
      /*  if confirmPasswordTextField != passwordTextField
        {
            return "Passwords do not match"
        }        //check if password is secure
        */
        
       func isPasswordValid(_ password : String) -> Bool {
            
            let passwordTest = NSPredicate(format: "SELF MATCHES %@", "^(?=.*[a-z])(?=.*[$@$#!%*?&])[A-Za-a\\d$@$#!%*?&]{8,}")
            return passwordTest.evaluate(with: password)
        }
        let cleanedPassword = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
        
        if isPasswordValid(cleanedPassword) == false {
            //password isn't secure enough
            return "Please make sure your password is at least 8 characters, contains a special character and a number."
        }
        
        return nil
    }
    
    @IBAction func signUpTapped(_ sender: Any) {
        // Validate fields
        let error = validateFields()
        
        func showError(_ message:String){
            errorLabel.text = error!
            errorLabel.alpha = 1
        }
        
        if error != nil {
            //There's something wrong with the fields show error message
            showError(error!)
            
        }
        else
        {
            
            //create cleaned versions of the data
            
            let firstName = firstNameTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            
            let email = emailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            
            let password = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            
                //create user
            Auth.auth().createUser(withEmail: email, password: password) { (result, err) in
                
                //check for errors
                if err != nil{
                    //there was an error
                    showError("Error creating user")
                }
                else{
                    //user was successfully created
                    let db = Firestore.firestore()
                    
                    db.collection("users").addDocument(data: ["firstname":firstName, "uid": result!.user.uid ]) { (error) in
                
                    if error != nil {
                        //showerror message
                        showError("System error: could not save user data (user was still created successfully, first name was not saved)")
                    }
                        }
                    self.transitionToHome()
                    
                }
                
            
        }
        //create user
        
        //transition to home screen
    }
    
    }
    
    func transitionToHome() {
        
        let homeViewController = storyboard?.instantiateViewController(withIdentifier: Constants.Storyboard.homeViewController) as? HomeViewController
        
        view.window?.rootViewController = homeViewController
        view.window?.makeKeyAndVisible()
    }


}

'''
Were you able to see my code?

Sorry Joseph,

So much happening here on this Code Crew forum that I missed your post 16 days ago.

Your SignUpViewController layout appears to be different to what Chris Ching specified in his version. By that I mean that the TextFields that he added were for first name, last name, email and password. Yours appears to be first name, email, password and password confirmation.

That’s OK if that is what you wanted to do but it means that the code you require in your SignUpViewController.swift file will be different to take that into account.

What I can see is that you have a function inside a function which is a problem. You have the isPasswordValid() function declared inside the validateFields() function. Take that out and place it below the validateFields() function and that should work.

Like this:

    func validateFields() -> String? {
        //check that all fields are filled in

        if firstNameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            emailTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            passwordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            confirmPasswordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == ""{

            return "Please fill in all fields"
        }

        /*  if confirmPasswordTextField != passwordTextField
         {
         return "Passwords do not match"
         }        //check if password is secure
         */

        let cleanedPassword = passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)

        if isPasswordValid(cleanedPassword) == false {
            //password isn't secure enough
            return "Please make sure your password is at least 8 characters, contains a special character and a number."
        }

        return nil
    }
    
    func isPasswordValid(_ password : String) -> Bool {

        let passwordTest = NSPredicate(format: "SELF MATCHES %@", "^(?=.*[a-z])(?=.*[$@$#!%*?&])[A-Za-a\\d$@$#!%*?&]{8,}")
        return passwordTest.evaluate(with: password)
    }

Ok, I tried that. But it still doesn’t allow me to make the account. The error still comes up.

Have you tried setting breakpoints in your code to allow you to check what is happening and to make sure that the logic is functioning as expected?

Yes but it doesn’t really help because the code runs fine and then it just drops me off at the end where the iPhone simulator comes up.

I’m thinking the code for the isPasswordValid function is off somehow. There has to be something wrong with the “SELF MATCHES %@”, “^(?=.[a-z])(?=.[$@$#!%?&])[A-Za-a\d$@$#!%?&]{8,}”) but I do not see what part of it is messed up

This is what mine looks like and yours (taken from your SignUpViewController.swift file) is directly below it. They are the same.
"SELF MATCHES %@", "^(?=.*[a-z])(?=.*[$@$#!%*?&])[A-Za-z\\d$@$#!%*?&]{8,}"
"SELF MATCHES %@", "^(?=.*[a-z])(?=.*[$@$#!%*?&])[A-Za-a\\d$@$#!%*?&]{8,}"

Don’t mess with it otherwise it definitely wont work.

Make sure that the password you have selected contains at least one lowercase letter, one uppercase letter, one special character and one number and is a least 8 characters in length.

So Test1234& is valid whereas test1234& is not valid.

Hmmmmm, something weird going on here. By the way, the password check does not ensure that you have a combination of upper and lowercase. The stipulation is 8 characters minimum and must have a number and a special character.

That said, I don’t now why your code is complaining since the test seems to me to be identical and mine works.

Aha, on very close examination I see that there is an error in that NSPredicate code you are using.

Mine is:
"SELF MATCHES %@", "^(?=.*[a-z])(?=.*[$@$#!%*?&])[A-Za-z\\d$@$#!%*?&]{8,}"
and yours is:
"SELF MATCHES %@", "^(?=.*[a-z])(?=.*[$@$#!%*?&])[A-Za-a\\d$@$#!%*?&]{8,}"
------------------------------------------------------ ^
Mine has A-Za-z whereas yours (for whatever the reason) has A-Za-a

So replace your predicate with this:

"SELF MATCHES %@", "^(?=.*[a-z])(?=.*[$@$#!%*?&])[A-Za-z\\d$@$#!%*?&]{8,}"