简体   繁体   English

Swift DispatchGroup导致错误:[Firebase / Firestore] [I-FST000001]无法到达Cloud Firestore后端

[英]Swift DispatchGroup causes error: [Firebase/Firestore][I-FST000001] Could not reach Cloud Firestore backend

I am using Firebase & Firestore to read in data using: 我正在使用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

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__"])") ). 当我删除任何DispatchGroup,group.enter()等的所有引用时,代码可以正常运行,尽管不是我想要的顺序(即,它运行print("ITEM_DATA: \\(itemData)")行,其中itemData为nil,直到以后才打印出print("Document data: \\(document.data() ?? ["key":"__data__"])") )的结果。 So I know that there isn't anything wrong with the actual request to Firebase. 因此,我知道对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: 但是,当我尝试在写入之前,使用上面的代码中的DispatchGroup来解决打印/返回itemData的问题时,当我运行该函数时,程序会给我错误代码:

[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. 收到此消息后,该程序再也不会连接到Firestore。 I've tried this with simulators and actual devices both with and without wifi, but to no avail. 我已经在有和没有wifi的模拟器和实际设备上进行了尝试,但是没有用。 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. 我知道这不是我的Internet连接问题,因为当我用DispatchGroup删除所有内容时它可以工作,但是我仍然无法弄清楚问题是什么或如何解决此问题。

Try entering and leaving the Dispatch Group being in a same Queue 尝试进入和离开调度组在同一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 看看在DispatchQueue异步关闭内部移动的enter语句

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: 编辑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 这是控制台的输出顺序

  1. "Hello" “你好”
  2. ITEM_DATA: ) ITEM_DATA :)

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 我知道我没有使用wait()并且wait()应该也可以工作,但是我的工作有点忙,所以现在无法使用wait进行测试

EDIT 2: 编辑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 刚刚意识到OP打算使用Dispatch group从异步函数返回值,因此更新了我的答案

You can't have a return statement from a async call no matter what logic you apply. 无论您采用哪种逻辑,都不能从异步调用获得return语句。 Dispatch group will not help you here, all that you need here is a closure or block 派遣小组在这里无济于事,您所需要的只是closureblock

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 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM