I am using Firebase & Firestore to read in data using:
var itemData: [String:Any]?
let docRef = db.collection("store").document(documentID)
let group = DispatchGroup()
group.enter()
DispatchQueue.global().async {
docRef.getDocument { (document, error) in
if let document = document, document.exists {
print("Document data: \(document.data() ?? ["key":"__data__"])")
itemData = document.data()
} else {
print("Document does not exist")
}
group.leave()
}
}
group.wait()
print("ITEM_DATA: \(itemData)")
return itemData
when I remove all references of any DispatchGroup, group.enter(), etc... the code runs okay, albeit not in the order that I want it to (ie it runs the print("ITEM_DATA: \\(itemData)")
line with itemData as nil and only later prints out the result of print("Document data: \\(document.data() ?? ["key":"__data__"])")
). So I know that there isn't anything wrong with the actual request to Firebase.
However, when I try to fix the issue of into printing/returning itemData
before I write to it, with the DispatchGroup as in the code above, when I run the function, the program gives me the error code:
[Firebase/Firestore][I-FST000001] Could not reach Cloud Firestore backend. Backend didn't respond within 10.000000 seconds.
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.
The program never connects to Firestore after I get this message. I've tried this with simulators and actual devices both with and without wifi, but to no avail. I know it's not a problem with my internet connection because it works when I remove all the stuff with DispatchGroup, but I still can't figure out what the issue is or how to get around this problem.
Try entering and leaving the Dispatch Group being in a same Queue
let group = DispatchGroup()
DispatchQueue.global().async {
group.enter()
docRef.getDocument { (document, error) in
if let document = document, document.exists {
print("Document data: \(document.data() ?? ["key":"__data__"])")
itemData = document.data()
} else {
print("Document does not exist")
}
group.leave()
}
}
group.wait()
print("ITEM_DATA: \(itemData)")
In case you are wondering what have I changed in your method?
Take a look at enter statement moving inside DispatchQueue
async closure
What might be causing the issue?
Entering a Dispatch Group being in different queue and leaving dispatch group while being in a different queue might be causing the issue
EDIT 1:
Hey, just tested your code and got it to work
let group = DispatchGroup()
DispatchQueue.global().async {
group.enter()
sleep(10)
debugPrint("Hello")
group.leave()
}
group.notify(queue: DispatchQueue.main) {
print("ITEM_DATA: )")
}
Here is the out put sequence from console
I know I am not using wait()
and wait()
should also work but little busy with my work so can't test with wait right now
EDIT 2:
Just realised that OP is intending to return a value from a async function using Dispatch group
hence updating my answer for the same
You can't have a return statement from a async call no matter what logic you apply. Dispatch group will not help you here, all that you need here is a closure
or block
func test(onCompletion completion: @escaping ([String:Any]) -> ()) {
DispatchQueue.global().async {
docRef.getDocument { (document, error) in
if let document = document, document.exists {
completion(document.data())
}
}
}
}
And call it as
self.test {[weak self] (data) in
debugPrint(data)
}
Hope it helps
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.