必须单击两次“注册”按钮才能使用户注册

时间:2019-01-19 18:54:21

标签: swift firebase

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

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

我认为这是当我单击“注册”时,passwordVerified和emailVerified为true,但不是usernameVerified。这很奇怪,因为usersnameVerified应该为true,因为我的用户名未使用并且超过3-15个字符。我添加了一些用于调试的打印语句,并看到在运行I/Error: /raw/storage/emulated/0/DCIM/Camera/IMG_20190109_141817_HDR.jpg (No such file or directory) W/System.err: java.io.FileNotFoundException: /raw/storage/emulated/0/DCIM/Camera/IMG_20190109_141817_HDR.jpg (No such file or directory) W/System.err: at java.io.FileInputStream.open0(Native Method) W/System.err: at java.io.FileInputStream.open(FileInputStream.java:200) at java.io.FileInputStream.<init>(FileInputStream.java:150) at okio.Okio.source(Okio.java:168) W/System.err: at okhttp3.RequestBody$3.writeTo(RequestBody.java:119) at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173) W/System.err: at okhttp3.MultipartBody.writeTo(MultipartBody.java:114) at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:72) W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) W/System.err: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126) W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254) W/System.err: at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200) at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) 之后将usernameVerified设置为true。

这是我的代码:

if statement where it checks if everything is verified

1 个答案:

答案 0 :(得分:1)

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

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

@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。它将使您的生活更加轻松。