1

I have made a basic app that lets users to signup and login. Here is the code to let the user sign up and it adds the user to the database. Once the user clicks(taps) on the signup button, an 'email verification' email will be sent to them.

var verificationTimer = Timer()

@objc func signupButtonPressed() {

    // Check that the text fields aren't empty
    if name.text!.isEmpty || email.text!.isEmpty || password.text!.isEmpty || countryTextField.text!.isEmpty {

        let emptyFieldAlert = UIAlertController(title: "Error", message: "Please fill out all the fields.", preferredStyle: .alert)
        emptyFieldAlert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
        self.present(emptyFieldAlert, animated: true)

    } else { // If none of the text fields are empty

        // Create a user
        func createUser(withEmail email: String, name: String, password: String, country: String) {

            // Sign up user only if all the text fields are filled
            Auth.auth().createUser(withEmail: email, password: password) { (result, error) in

                if result != nil {

                    // Send an 'email verification' email to the user
                    Auth.auth().currentUser?.sendEmailVerification(completion: nil)

                    // Set a timer to call the emailverification function every second
                    self.verificationTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.checkIfEmailIsVerified), userInfo: nil, repeats: true)

                } else {

                    // Error: show error message
                    print("Failed to sign user up with error: ", error!.localizedDescription)
                    let emptyFieldAlert = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
                    emptyFieldAlert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
                    self.present(emptyFieldAlert, animated: true)

                    return
                }}}


        createUser(withEmail: self.email.text!, name: self.name.text!, password: self.password.text!, country: self.countryTextField.text!)

I have created a timer that calls a function every second, the function checks if the user has verified their email. And if the user has verified their email, the timer will stop and the user will be directed to the main page of the app. I've given the code below. NOTE: A user account will be created regardless of the verification of the email.

// Check if the user has verified the email
@objc func checkIfEmailIsVerified() {
    Auth.auth().currentUser?.reload(completion: {(error) in
        if error == nil {

            if Auth.auth().currentUser!.isEmailVerified {

                // Stop the timer
                self.verificationTimer.invalidate()
                print(self.verificationTimer)

                // User verified, go to main page
                let mainPage = MainScreen()
                self.present(mainPage, animated: true, completion: nil)

            }
        }
    })
} 

I also have a function on my main page that keeps the user logged in unless they have logged out. Here is the code for that:

// Check if the user is signed in
func authenticateUserAndConfigure() {

    if Auth.auth().currentUser == nil {
        DispatchQueue.main.async {
            // If user isn't singed in, user will be directed to the login page
            self.present(LoginScreen(), animated: false, completion: nil)
        }
    }
}

This works almost perfectly, the problem is, a user is created regardless of the email verification, if the user quits the app and relaunches it after clicking (tapping) on sign up without verifying their email, the user will be directed to the main page (last code snippet). So basically, I want the user to get added to the database only after the user verifies their email.

halfer
  • 19,824
  • 17
  • 99
  • 186
Abdullah Ajmal
  • 431
  • 5
  • 17
  • "is there a way to disable the account and only enable it once the email is verified?" This has been asked before (see a.o. [1](https://stackoverflow.com/q/52236160), [2](https://stackoverflow.com/q/48028927), [3](https://stackoverflow.com/q/54605559)), and is currently not possible. I highly recommend removing this part from your question and updating the title, to reduce the chance of it getting closed as a duplicate. – Frank van Puffelen Jun 19 '19 at 15:04
  • Oh, thanks a lot. :) – Abdullah Ajmal Jun 19 '19 at 15:08

2 Answers2

1

I figured it out, here is the code:

// Check if the user is signed in
func authenticateUserAndConfigure() {

    if Auth.auth().currentUser == nil {
        DispatchQueue.main.async {
            // If user isn't singed in, user will be directed to the login page
            self.present(LoginScreen(), animated: false, completion: nil)
        }
    } else {

        if Auth.auth().currentUser?.isEmailVerified == false {

            DispatchQueue.main.async {
                // If user hasn't verified their email, the user will be directed to the login page
                self.present(LoginScreen(), animated: false, completion: nil)
            }

        }
    }
}

This checks if the user has verified their email and if they haven't, they will be logged out.

Abdullah Ajmal
  • 431
  • 5
  • 17
0

You have to save a flag that indicates whether the user is verified or not. A user should be created upon sign up, even if it's not verified. Add an entry to User in the db isVerified and check that on startup.

Lirik
  • 3,167
  • 1
  • 30
  • 31