必须单击两次“注册"按钮才能使用户注册 [英] Sign up button must be clicked twice in order for user to sign up

查看:43
本文介绍了必须单击两次“注册"按钮才能使用户注册的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注册后,由于某种原因,我必须单击两次注册按钮,然后才能创建我的帐户.第一次单击它时,即使电子邮件,用户名和密码都经过验证,也会出现错误标签.

When I sign up, for some reason I must click the sign up button twice before my account will be created. The first time I click it, an error label comes out even though email, username, and password is verified.

以下是视频: https://youtu.be/LTHElDXUWts

我认为这是当我单击注册"时,passwordVerified和emailVerified为true,但不是usernameVerified.这很奇怪,因为usersnameVerified应该为true,因为我的用户名未使用并且超过3至15个字符.我添加了一些用于调试的打印语句,并看到在 if语句检查所有内容是否已验证后,将usernameVerified设置为true.

I think what is going on is that when I click sign up, passwordVerified and emailVerified is true but not usernameVerified. This is weird since usersnameVerified should be true since my username is not taken and is more than 3-15 characters. I added some print statement for debugging and saw that the usernameVerified is set to true AFTER the if statement where it checks if everything is verified is ran.

这是我的代码:

 @IBAction func onSignUp(_ sender: Any) {

        print("Sign Up pressed")
        isValidUsername(username: usernameTextField.text!)
        print("[SIGN UP] - Username: \(usernameVerified)")
        isValidEmail(email: emailTextField.text!)
        print("[SIGN UP] - Email: \(emailVerified)")
        isValidPassword(password: passwordTextField.text!)
        print("[SIGN UP] - Password: \(passwordVerified)")



        if passwordVerified && emailVerified && usernameVerified {

            Auth.auth().createUser(withEmail: emailTextField.text!, password: passwordTextField.text!) { (authResult, error) in
                if error != nil {
                    self.errorLabel.alpha = 1
                    self.errorLabel.text = error?.localizedDescription
                    self.shake(viewToShake: self.errorLabel)
                    return
                }

                guard let user = authResult?.user else {
                    return
                }


                //Successfully Authenticated User
                let ref = Database.database().reference(fromURL: "https://heytest.firebaseio.com/")
                let usersReference = ref.child("users").child(user.uid)
                let values = ["username": self.usernameTextField.text!, "email": self.emailTextField.text!, "games-played": "0"] 
                usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
                    if err != nil {
                        print(err!)
                        return
                    }

                    //Successfully registered user's data to database
                    print("[SIGN UP] - Successfully Signed Up")
                    self.errorLabel.alpha = 0
                    self.present((self.storyboard?.instantiateViewController(withIdentifier: "TabBarViewController"))!, animated: false, completion: nil)


                })
            }

        } else {

            errorLabel.alpha = 1
            shake(viewToShake: errorLabel)
            print("Password/Email/Username verification not complete!")
            print("[SIGN UP] - Password: \(passwordVerified)")
            print("[SIGN UP] - Username: \(usernameVerified)")
            print("[SIGN UP] - Email: \(emailVerified)")

        }

    }

    //MARKUP: Validations/Verifications

    //Email Verification (Must follow correct email format: example@gmail.com)
    func isValidEmail(email: String) {

        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
        if valid {
            valid = !email.contains("Invalid email id")
        }

        if valid == false {


            emailLabel.textColor = UIColor.red
            emailLabel.text = "EMAIL INVALID"
            emailTextField.layer.addBorder(edge: UIRectEdge.bottom, color: UIColor.red, thickness: 1.5)

        } else {
            emailVerified = true
            emailTextField.layer.addBorder(edge: UIRectEdge.bottom, color: UIColor.black, thickness: 1.5)
            emailLabel.textColor = UIColor.black
            emailLabel.text = "EMAIL"
        }
    }


    //Password Verification (Must be greater than 8 digits
    func isValidPassword(password: String) {

        let passwordRegex = ".{8,}"
        var valid = NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: password)

        if valid {
            valid = !password.contains("Invalid password id")
        }

        if valid == false {


            passwordLabel.textColor = UIColor.red
            passwordLabel.text = "PASSWORD MUST BE AT LEAST 8 DIGITS"
            passwordTextField.layer.addBorder(edge: UIRectEdge.bottom, color: UIColor.red, thickness: 1.5)

        } else {
            passwordVerified = true
            passwordTextField.layer.addBorder(edge: UIRectEdge.bottom, color: UIColor.black, thickness: 1.5)
            passwordLabel.textColor = UIColor.black
            passwordLabel.text = "PASSWORD"
        }
    }

    //Username Verification (Must be between 3-15 charaters w/ username not taken)
    func isValidUsername(username: String) {
        let usernameRegex = ".{3,15}"
        var valid = NSPredicate(format: "SELF MATCHES %@", usernameRegex).evaluate(with: username)

        if valid {
            valid = !username.contains("Invalid username id")
        }

        if valid == false {


            usernameLabel.textColor = UIColor.red
            usernameLabel.text = "USERNAME MUST BE 3-15 CHARS"
            usernameTextField.layer.addBorder(edge: UIRectEdge.bottom, color: UIColor.red, thickness: 1.5)

        } else {
            let ref = Database.database().reference(fromURL: "https://heytest.firebaseio.com/")
            let usernamesRef = ref.child("users")
            usernamesRef.queryOrdered(byChild: "username").queryEqual(toValue: username).observeSingleEvent(of: .value, with: { (snapshot) in
               // if there is data in the snapshot reject the registration else allow it

                if (snapshot.value! is NSNull) {

                    self.usernameVerified = true
                    print("[SIGN UP] - Username: \(self.usernameVerified)")
                    self.usernameTextField.layer.addBorder(edge: UIRectEdge.bottom, color: UIColor.black, thickness: 1.5)
                    self.usernameLabel.textColor = UIColor.black
                    self.usernameLabel.text = "USERNAME"

                } else {

                    self.usernameVerified = false
                    self.usernameTaken = true
                    self.usernameLabel.textColor = UIColor.red
                    self.usernameLabel.text = "USERNAME TAKEN"
                    self.usernameTextField.layer.addBorder(edge: UIRectEdge.bottom, color: UIColor.red, thickness: 1.5)

                }

            }) { (error) in
                print(error.localizedDescription)
            }



        }
    }

推荐答案

好吧,我试图在您的代码中添加一些内容,但是有点难以阅读.您应该真正考虑对其进行重构.

Well, I tried to add a few thing in you code but it is a bit difficult to read. You should really think about refactoring it.

无论如何,问题在于您从不等待查询结果返回,而只是让它运行.请记住,Firebase是异步的.在您的情况下,我建议您对 isValidUsername 方法使用一个完成块.这是给您的一些代码.不知道它是否会运行,因为如果不创建您拥有的所有UI组件,我将无法编译.在下面的代码中,我删除了一堆您的代码,这些代码如果未经验证,则UI会更改.我也删除了已验证的变量,因为在这种情况下,您将不再需要它们.我注释了我添加的所有代码,以便您可以更轻松地理解它.

Anyway, the problem is that you are never waiting for the result from the query to return, and you are just letting it run. Remember that Firebase is async. In your case I suggest you using a completion block for the isValidUsername method. Here is some code for you. Not sure if it will run as I cannot compile without creating all the UI components that you have. In the code below I removed a bunch of your code that does the UI changes if it is not verified. I also removed your verified variables since in this case you won't need them anymore. I commented all the code that I added so you can understand it easier.

@IBAction func onSignUp(_ sender: Any) {

        print("Sign Up pressed")
        guard let email = emailTextField.text else { return }
        guard let password = passwordTextField.text else { return }
        guard let userName = usernameTextField.text else { return }

        if isValidEmail(email: email) && isValidPassword(password: password) {
            // HERE YOU USE THE CLOSURE
            isValidUsername(username: userName) { (verified, error) in
                if error != nil {
                    // IF THERE IS ERROR RETURN
                    return
                }
                guard let verified = verified else { return }
                // IF IT IS A VALID USERNAME, PROCEED WITH SIGNUP
                if verified {
                    Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
                        if error != nil {
                            return
                        }

                        guard let user = authResult?.user else {
                            return
                        }

                        //Successfully Authenticated User
                        let ref = Database.database().reference(fromURL: "https://heytest.firebaseio.com/")
                        let usersReference = ref.child("users").child(user.uid)
                        let values = ["username": self.usernameTextField.text!, "email": self.emailTextField.text!, "games-played": "0"]
                        usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
                            if err != nil {
                                print(err!)
                                return
                            }

                            //Successfully registered user's data to database
                            print("[SIGN UP] - Successfully Signed Up")
                            self.present((self.storyboard?.instantiateViewController(withIdentifier: "TabBarViewController"))!, animated: false, completion: nil)


                        })
                    }
                }
            }
        } else {

        }

    }

    //MARKUP: Validations/Verifications
    //Email Verification (Must follow correct email format: example@gmail.com)
    func isValidEmail(email: String) -> Bool {

        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
        if valid {
            valid = !email.contains("Invalid email id")
        }

        if valid == false {

            return false

        } else {

            return true
        }
    }


    //Password Verification (Must be greater than 8 digits
    func isValidPassword(password: String) -> Bool {

        let passwordRegex = ".{8,}"
        var valid = NSPredicate(format: "SELF MATCHES %@", passwordRegex).evaluate(with: password)

        if valid {
            valid = !password.contains("Invalid password id")
        }

        if valid == false {

            return false

        } else {

            return true
        }
    }

    //Username Verification (Must be between 3-15 charaters w/ username not taken)
    // HERE IS A CLOSURE
    typealias validateClosure = (Bool?, Error?) -> Void
    func isValidUsername(username: String, completion: @escaping validateClosure) {
        let usernameRegex = ".{3,15}"
        var valid = NSPredicate(format: "SELF MATCHES %@", usernameRegex).evaluate(with: username)

        if valid {
            valid = !username.contains("Invalid username id")
        }

        if valid == false {

        } else {
            let ref = Database.database().reference(fromURL: "https://heytest.firebaseio.com/")
            let usernamesRef = ref.child("users")
            usernamesRef.queryOrdered(byChild: "username").queryEqual(toValue: username).observeSingleEvent(of: .value, with: { (snapshot) in
                // if there is data in the snapshot reject the registration else allow it

                if (snapshot.value! is NSNull) {
                    // RETURN TRUE IF VERIFIED
                    completion(true, nil)

                } else {
                    // RETURN FALSE IF NOT VARIFIED
                    completion(false, nil)

                }

            }) { (error) in
                // RETURN FALSE AND THE ERROR
                completion(false, error)
                print(error.localizedDescription)
            }

        }
    }

希望它会有所帮助.并请您真正考虑一下如何将所有进行网络调用和业务逻辑的代码移至另一个类,并移离viewController.它将使您的生活更加轻松.

Hope it helps. And please really give it some thought about moving all the code that does network calls and business logic to another class and away of the viewController. It will make your life much easier later.

这篇关于必须单击两次“注册"按钮才能使用户注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆