我正在使用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 groupclosure
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)
    }

希望有帮助

09-11 20:16