evanhaus
evanhaus

Reputation: 737

(Firebase) Assign value to global variable from a returned completion handler function

I have a function that retrieves the "users" node of my Firebase database, and I am trying to assign a global variable equal to the number of users that are in this "users" node like so:

func getUsers(completionHandler:@escaping (Int) -> ()) {

    let ref = Database.database().reference().child("users")

    ref.observe(.childAdded, with: { (snapshot) in
        if let dictionary = snapshot.value as? [String: AnyObject] {

            let user = User()

            user.id = snapshot.key
            user.setValuesForKeys(dictionary)                
            self.users.append(user)
            completionHandler(self.users.count)
        }

    }, withCancel: nil)

}

Then, in the viewDidLoad() function, I try to assign a global variable equal to the number of users in the "users" node like this:

var userCount: Int?

override func viewDidLoad() {
    super.viewDidLoad()

    getUsers(){ (count) in
        self.userCount = count
    }

    print(userCount)
}

This prints nil, and it should be 12, which is the amount of users I added to my Firebase database. Since I am somewhat unfamiliar with completion handlers, I am unsure how to fix this.

Any and all help is greatly appreciated.

Upvotes: 1

Views: 571

Answers (1)

Torongo
Torongo

Reputation: 1091

Your completion closure is @escaping that is async for that reason print(userCount) get executed before the completion block returns and you are getting nil. Try This:

var userCount: Int?

override func viewDidLoad() {
    super.viewDidLoad()

    getUsers(){ (count) in
        self.userCount = count
        print(self.userCount)
    }
}

Or you can remove @escaping and make your completion closure sync.

func getUsers(completionHandler:(Int) -> ()) {

    let ref = Database.database().reference().child("users")

    ref.observe(.childAdded, with: { (snapshot) in
        if let dictionary = snapshot.value as? [String: AnyObject] {

            let user = User()

            user.id = snapshot.key
            user.setValuesForKeys(dictionary)                
            self.users.append(user)
            completionHandler(self.users.count)
        }

    }, withCancel: nil)

}

Upvotes: 1

Related Questions