Firebase Authentication Tutorial with swift (button problem)

I was doing the tutorial and i was close to the end. I ran the app and was doing the tester for the sign up but when I press the sign up button it doesn’t actually let me go through it and takes me to an error I guess in the system

the only difference that I see that I have from the video is that I didn’t put the ibaction here because it would give me an error saying “only instances methods can be declared @IBAction and asks me to remove it”

" func signUpButtonTapped(_ sender: Any) {

    let error = validateFields()
    
    if error != nil {
        showError(message: error!)

…"

Can you post the complete code from your SignUpViewController so that we can see everything in context.

When you post your code, place 3 back-ticks ``` on the line before and the line after so that it formats the code correctly. The back-tick character is the one below the tilde ~ on your keyboard.

import UIKit
import FirebaseAuth
import Firebase
import FirebaseFirestore


class SignUpViewController: UIViewController {
    
    @IBOutlet weak var FirstNameTextField: UITextField!
    
    @IBOutlet weak var LastNameTextField: UITextField!
    
    @IBOutlet weak var EmailTextField: UITextField!
    
    @IBOutlet weak var PasswordTextField: 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
        
            //Style the elements
        if LastNameTextField == nil{
            return
        }
    
        Utilities.styleTextField(FirstNameTextField)
        Utilities.styleTextField(LastNameTextField)
        Utilities.styleTextField(EmailTextField)
        Utilities.styleTextField(PasswordTextField)
        Utilities.styleFilledButton(SignUpButton)
       
        
    
    }

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destination.
        // Pass the selected object to the new view controller.
    }
    */
    // Validate the Fields
    func validateFields() -> String? {
        if FirstNameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            LastNameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            EmailTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            PasswordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
            
            return "Please fill in all fields."
        }
        let cleanedPassword = PasswordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
        
        if  Utilities.isPasswordValid(cleanedPassword) == false {
            
            return "Please make sure you password is at least 8 characters long, contains a special character and a number."
        }
        
        return nil
    }
    func showError( message:String) {
        ErrorLabel.text = message
        ErrorLabel.alpha = 1
    
        func signUpButtonTapped(_ sender: Any) {
        
        let error = validateFields()
        
        if error != nil {
            showError(message: error!)
        }
        else {
            
            let firstname = FirstNameTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            let lastname = LastNameTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            let email = EmailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            let password = PasswordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            
            // Create the user
            Auth.auth().createUser(withEmail: email, password: password) { (result, err) in
                if err != nil {
                    self.showError(message: "Error creating user")
                }
                else {
                    let db = Firestore.firestore()
                    
                    db.collection("users").addDocument(data:["firstname":firstname, "lastname": lastname, "uid": result!.user.uid]) { (error) in
                        
                        if error != nil {
                            self.showError(message: "Error saving user data")
                            
                        }
                    }
                    
                        
                       transitionToHome()
            }
            
            // Transition to the home screen
            
            
        }
       
        
    
    }
    

    
     }
    
    func transitionToHome() {
        
        let homeViewcontroller =  storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
        
        view.window?.rootViewController = homeViewcontroller
        view.window?.makeKeyAndVisible()
        
}
    }
}

There was a closing brace missing after the showError() function which meant that the signUpButtonTapped() function was inside showError().

The following is the corrected code so copy and paste that into your SignUpViewController and see how that goes.

import UIKit
import FirebaseAuth
import Firebase
import FirebaseFirestore


class SignUpViewController: UIViewController {
    
    @IBOutlet weak var FirstNameTextField: UITextField!
    
    @IBOutlet weak var LastNameTextField: UITextField!
    
    @IBOutlet weak var EmailTextField: UITextField!
    
    @IBOutlet weak var PasswordTextField: 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
        
        //Style the elements
        if LastNameTextField == nil{
            return
        }
        
        Utilities.styleTextField(FirstNameTextField)
        Utilities.styleTextField(LastNameTextField)
        Utilities.styleTextField(EmailTextField)
        Utilities.styleTextField(PasswordTextField)
        Utilities.styleFilledButton(SignUpButton)
    }
    
    /*
     // MARK: - Navigation
     
     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     // Get the new view controller using segue.destination.
     // Pass the selected object to the new view controller.
     }
     */
    
    // Validate the Fields
    func validateFields() -> String? {
        if FirstNameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            LastNameTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            EmailTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" ||
            PasswordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
            
            return "Please fill in all fields."
        }
        let cleanedPassword = PasswordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
        
        if  Utilities.isPasswordValid(cleanedPassword) == false {
            
            return "Please make sure you password is at least 8 characters long, contains a special character and a number."
        }
        
        return nil
    }
    
    func showError( message:String) {
        ErrorLabel.text = message
        ErrorLabel.alpha = 1
    }
    
    func signUpButtonTapped(_ sender: Any) {
        
        let error = validateFields()
        
        if error != nil {
            showError(message: error!)
        }
        else {
            
            let firstname = FirstNameTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            let lastname = LastNameTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            let email = EmailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            let password = PasswordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
            
            // Create the user
            Auth.auth().createUser(withEmail: email, password: password) { (result, err) in
                if err != nil {
                    self.showError(message: "Error creating user")
                }
                else {
                    let db = Firestore.firestore()
                    
                    db.collection("users").addDocument(data:["firstname":firstname, "lastname": lastname, "uid": result!.user.uid]) { (error) in
                        
                        if error != nil {
                            self.showError(message: "Error saving user data")
                            
                        }
                    }
                    
                    transitionToHome()
                }
                // Transition to the home screen
            }
        }
    }
    
    func transitionToHome() {
        
        let homeViewcontroller =  storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController) as? HomeViewController
        
        view.window?.rootViewController = homeViewcontroller
        view.window?.makeKeyAndVisible()
        
    }    
}

I tried doing that now it still gives me that same thread 1 error.

So when you tap on SignUp you get the error but when you tap on Login does that work OK?

Check that the Storyboards segues from each button are correct.

I tried doing that and now I get an error of Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value. By the way I really appreciate the help, I’m pretty new at this so this really helps.

Do you get an error when you tap on Sign Up as well as when you tap on Login?