我正在使用Firebase&Firestore读取数据,使用:
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
当我删除任何DispatchGroup、group.enter()等的所有引用时。。。代码运行正常,尽管不是按照我希望的顺序(即,它运行带有itemData的
print("ITEM_DATA: \(itemData)")
行,并在稍后打印出print("Document data: \(document.data() ?? ["key":"__data__"])")
的结果)。所以我知道对Firebase的实际请求没有任何错误。但是,当我试图在写入之前解决打印/返回
itemData
的问题时,使用上面代码中的DispatchGroup,当我运行该函数时,程序会给出错误代码:[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.
我收到这条消息后,程序就再也无法连接到Firestore。我试过在模拟器和实际设备上使用wifi和不使用wifi,但都没有成功。我知道这不是我的网络连接的问题,因为当我用DispatchGroup删除所有内容时,它会起作用,但我仍然无法找出问题所在或如何解决这个问题。
最佳答案
尝试进入和离开调度组在同一个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)")
如果你想知道我改变了你的方法?
看看enter语句在异步闭包中的移动
是什么导致了这个问题?
进入位于不同队列中的调度组,离开位于不同队列中的调度组可能会导致此问题
编辑1:
嘿,刚刚测试了你的代码,然后开始工作了
let group = DispatchGroup()
DispatchQueue.global().async {
group.enter()
sleep(10)
debugPrint("Hello")
group.leave()
}
group.notify(queue: DispatchQueue.main) {
print("ITEM_DATA: )")
}
这是控制台的输出顺序
“你好”
项目数据:)
我知道我没有使用
DispatchQueue
并且wait()
也应该工作,但是我的工作很忙,所以现在不能用wait来测试编辑2:
刚刚意识到OP打算使用
wait()
从异步函数返回一个值,因此更新了我的答案无论应用什么逻辑,都不能从异步调用获取返回语句。派遣组在这里帮不了你,你只需要一个
Dispatch group
或closure
func test(onCompletion completion: @escaping ([String:Any]) -> ()) {
DispatchQueue.global().async {
docRef.getDocument { (document, error) in
if let document = document, document.exists {
completion(document.data())
}
}
}
}
并称之为
self.test {[weak self] (data) in
debugPrint(data)
}
希望有帮助