Reputation: 737
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
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