Frank Zappa
Frank Zappa

Reputation: 451

Swift Firebase 4.0 - observeSingleEvent not returning data set (but authentication is working)

I have been working with Firebase on Android for the last 12 months+, with success. I just switched over to Swift and am attempting to read data from the same Firebase database I created and have been using the last 12 months+. Since there is security applied to the FB DB the first thing I did was to get FB authentication (from Swift) working. This works. Now, I am trying to get a simple observeSingleEvent operational and am struggling.

The Firebase DB is the same old stuff. It has a users node off of the root. For starters I would just like to read in a user from the user's node. I know authentication is working because when I submit my email and password I receive a confirmation. When the email / password are wrong I do not get confirmation. Given this validates my connection to the DB and as a test I stuck the following code in right after login validation.

When I debug this it simply skips from the "self.ref?.child("users").observeSingleEvent..." to the bracket below. i.e. It never acknowledges there is data available, but there is data available.

To avoid anyone asking "What do you need?" What I am looking for is an answer to why I receive no data result set with the code below given there is data in the FB DB and I have been reading/writing that data on Android for the last 12+ months.

Any/all help is welcome as I cut my teeth on Swift / FB 4.0

@IBAction func signInButtonTapped(_ sender: UIButton) {

    // TODO: Do some form validation on the email and password

    if let email = emailTextField.text, let pass = passwordTextField.text {

        // Check if it's sign in or register
        if isSignIn {
            // Sign in the user with Firebase
            Auth.auth().signIn(withEmail: email, password: pass, completion: { (user, error) in

                // Check that user isn't nil
                if let u = user {
                    // User is found, go to home screen

                    self.ref = Database.database().reference()
                    self.ref?.child("users").observeSingleEvent(of: .value, with: {( snapshot) in
                        let value = snapshot.value as? NSDictionary
                        let username = value?["username"] as? String ?? ""
                        print ("***   " + username)

                    })           
                }
                else {
                    // Error: check error and show message
                }

            })

        }

Upvotes: 2

Views: 1636

Answers (1)

3stud1ant3
3stud1ant3

Reputation: 3606

Since observeSingleEvent is an async call so it is running on the background thread, that is why it jumps on to the next bracket when you put a break point on self.ref, because it doesnt block the current thread of execution and does execute after sometime on background thread

One way to do is this:

@IBAction func signInButtonTapped(_ sender: UIButton) {

    // TODO: Do some form validation on the email and password

    if let email = emailTextField.text, let pass = passwordTextField.text {

        // Check if it's sign in or register
        if isSignIn {
            // Sign in the user with Firebase
            Auth.auth().signIn(withEmail: email, password: pass, completion: { (user, error) in

                // Check that user isn't nil
                if let u = user {
                    // User is found, go to home screen

                    self.fetchUserName { fetchedUserName in
                        print(fetchedUserName)

                    }        
                }
                else {
                    // Error: check error and show message
                }

            })

        }

func fetchUserName(completionHandler: @escaping (String) -> Void) {


      self.ref = Database.database().reference()
      self.ref?.child("users").observeSingleEvent(of: .value, with: {( snapshot) in
            //let value = snapshot.value as? NSDictionary
            if let value = snapshot.value as? [String: Any] {
                  print(value)
                  let username = value["username"] as? String ?? ""

                  print (username)
                  completionHandler(username)

            }

      })


}

Upvotes: 2

Related Questions