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

Posted

技术标签:

【中文标题】从 Firebase 获取数据 - 完成处理程序?【英文标题】:Fetching data from Firebase - completion handler? 【发布时间】:2020-05-26 08:06:12 【问题描述】:

我需要从 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**
                    
                
            
        
    

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

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

那么我怎样才能保证我的数据数组已经准备好呢?

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

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

【问题讨论】:

【参考方案1】:

您可以使用DispatchGroup。使用enter()leave() 函数来决定新任务何时开始和完成。然后,使用notify() 函数在调度组为空时执行您需要执行的操作(由进入和离开操作的计数决定)。

【讨论】:

以上是关于从 Firebase 获取数据 - 完成处理程序?的主要内容,如果未能解决你的问题,请参考以下文章

从firebase调用数据需要完成处理程序?

使用完成处理程序按顺序执行操作

使用 Firebase 的 Swift 完成处理程序

如何使用 swift 和 firebase 正确使用完成处理程序?

等待循环完成,DispatchGroup 使用 Swift 从 firebase 获取数据

完成处理程序没有被调用为假定的 Swift