Code not finishing the function, it is ending execution halfway through

ぐ巨炮叔叔 提交于 2020-07-23 06:48:13

问题


My code is as follows:

@IBAction func clicked(_ sender: Any) {
        let ref = Database.database().reference()
        let pass = password.text
        var firpass = ""
        var bool = false;
        ref.child(name.text as! String).child("password").observeSingleEvent(of: .value, with: { dataSnapshot in
          firpass = dataSnapshot.value as! String
            if firpass == pass {
                bool = true
                print("in here")
            }
        })
        print(bool)
        if bool {
            self.sendname = name.text!
            let vc = DatabaseTableViewController(nibName: "DatabaseTableViewController", bundle: nil)
            vc.finalName = self.sendname
            navigationController?.pushViewController(vc, animated: true)
            performSegue(withIdentifier: "username", sender: self)
        } else {
            let alert = UIAlertController(title: "Error", message: "Incorrect username or password", preferredStyle: UIAlertController.Style.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }

"in here" gets printed, but bool is never printed and the alert is showing. Why does my code not enter the if bool block and output the alert?


回答1:


Data is loaded from Firebase asynchronously, since it may take a while. Instead of making your app wait for the data (which would be a bad user experience), your main code continues while the data is being loaded, and then once the data is available your closure is called.

This explains the behavior you're seeing: by the time your runs, the hasn't run yet.

the solution is as simple as it is initially confusing and annoying: any code that needs the data from the database must be inside the closure, or be called from there.

So for example:

ref.child(name.text as! String).child("password").observeSingleEvent(of: .value, with: { dataSnapshot in
  firpass = dataSnapshot.value as! String
    if firpass == pass {
        bool = true
        print("in here")
    }
    print(bool)
    if bool {
        self.sendname = name.text!
        let vc = DatabaseTableViewController(nibName: "DatabaseTableViewController", bundle: nil)
        vc.finalName = self.sendname
        navigationController?.pushViewController(vc, animated: true)
        performSegue(withIdentifier: "username", sender: self)
    } else {
        let alert = UIAlertController(title: "Error", message: "Incorrect username or password", preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
})

Also see:

  • Firebase with Swift 3 counting the number of children
  • Array of struct not updating outside the closure
  • getting data out of a closure that retrieves data from firebase (showing examples with custom callbacks and delegates)
  • How to reload data after all Firebase calls finished? (showing how to use a dispatch group)
  • Finish all asynchronous requests before loading data? (another example using a dispatch group)



回答2:


Also you have to set variable bool to false when you are navigating to next view controller after login. So that you login again and if password is wrong then you can not navigate to next page and only it shows alert for wrong password.



来源:https://stackoverflow.com/questions/59710440/code-not-finishing-the-function-it-is-ending-execution-halfway-through

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!