I'm trying to get the count of documents where located in Firebase.
Whenever I try to assign the count of documents a variable in closure, the value is null
.
According to articles, networking takes some time and it happens asynchronously. So due to asynchronous behaviour, returning a value inside a closure might happen before assignment of the value.
I tried to add dispatchqueue.main.async but it didn't work.
Here is my code
func getEventCount () -> Int? {
var count: Int?
db.collection("Events").whereField("owner", isEqualTo: currentUser.email).getDocuments { (snapshot, error) in
if error != nil {
print(error)
}else {
DispatchQueue.main.async {
if let snapshot = snapshot {
count = snapshot.count
}
}
}
}
return count
}
My main goal is to get count of documents from database and assign a variable called count
.
Once it is a Async call - you cannot synchronously return the value from the function. You should accept a callback to the function that will accept the count. That callback function or closure will be passed the value asynchronously.
func getEventCount (callback: @escaping(Result<Int, Error>) -> Void) {
db.collection("Events").whereField("owner", isEqualTo: currentUser.email).getDocuments { (snapshot, error) in
if error != nil {
let result = Result.failure(error)
callback(result)
}else if let snapshot = snapshot {
let result = Result.success(snapshot.count)
callback(result)
} else {
let result = Result.failure(SomeCustomAppError)
callback(result)
}
}
}
Then you can call this function passing in a callback
self.getCount() { result in
switch result {
case .success(let count): /// use count
print(count)
// only here u can assign the count value to ur variable
case .error(let error): /// handle error
print(error.localizedDescription)
}
}
Note: In the above I've used the Result datatype from Swift standard library - https://developer.apple.com/documentation/swift/result so that both error or result can be passed back