从Firebase提取数据-完成处理程序?

时间:2020-05-26 08:06:12

标签: swift firebase google-cloud-firestore swiftui

我需要从Firebase数据库中获取数据,并且我的功能由两个循环(一个在另一个内部)表示。 代码如下:

// THE 1ST LOOP FETCHING THE LIST OF EQUIPMENT
self.db.collection("fl_content")
            .whereField("_fl_meta_.schema", isEqualTo: "equipment")
            .whereField("active", isEqualTo: true)
            .getDocuments() {
                (querySnapshot, err) in

                if let err = err {
                    print("Error getting documents: \(err)");
                } else {
                    var imagesToFetch: [String : String] = [:]

                    for equipmentDocument in querySnapshot!.documents {
                        if
                            let name = equipmentDocument.data()["name"] as? String, let images = equipmentDocument.data()["image"] as? [DocumentReference], let active = equipmentDocument.data()["default"] as? Bool, let def = equipmentDocument.data()["default"] as? Bool {
                            var documentData: [String: Any] = [:]
                            documentData["name"] = name
                            documentData["active"] = active
                            documentData["default"] = def
                            documentData["image"] = images[0].documentID
                            equipmentData[equipmentDocument.documentID] = documentData
                            if images.indices.contains(0) {

                                if FileManager.fileExists(path: "\(Constants.fileSavePath)\(images[0].documentID)") {
                                    self.toolList.append(
                                        Equipment(
                                            fbid: equipmentDocument.documentID,
                                            name: name,
                                            image: (documentData["image"] != nil) ? FileManager.fileToUIImage(path: images[0].documentID) : nil,
                                            active: active,
                                            def: def)
                                    )
                                } else {
                                    imagesToFetch[equipmentDocument.documentID] = images[0].documentID
                                }
                            }

                        } else {
                            print("No 'name' or 'image' found for this journey")
                        }
                    }
                    // got all data, let's get file paths and check if files exist
                    if(!imagesToFetch.isEmpty) {
                        // fetching paths to the images
                        self.db.collection("fl_files").whereField("_fl_meta_.docId", in: Array(imagesToFetch.values)).getDocuments() { 
                            (querySnapshot, err) in
                            if let err = err {
                               print("Error getting documents: \(err)");
                            } else {
                               for imageDocument in querySnapshot!.documents {
                                 // Getting file paths from Firebase .....
                                 **HERE COMES THE 2ND LOOP FETCHING THE IMAGES FOR EACH GEAR**
                    }
                }
            }
        }
    }
}

问题是我需要形成一个数组并将这个数组(当所有请求都完成并且获取数据时)传递给下一个View。但是我不知道如何判断是否所有Firebase请求都已处理。

如果我将代码放置在这2个循环之后,则可能在获取所有数据之前执行了代码,对吗?一些请求可能仍在进行中

那我如何保证包含数据的阵列已经准备好?

当此类数据用于UI更新时,我真的不在乎所有操作都完成了,因为UI订阅了我的“已发布”变量,但是在这种情况下,我希望能够检测到何时所有请求完成并获取数据。

做到这一点的最佳方法是什么?我应该使用计数器检查所有请求是否已完成并使用完成处理程序吗?

1 个答案:

答案 0 :(得分:1)

您可以使用DispatchGroup。使用enter()leave()函数来确定新任务何时开始和完成。然后,使用notify()函数来执行调度组为空(这取决于计数输入和离开操作来决定)时需要做的所有事情。