Получение данных из Firebase - обработчик завершения? - PullRequest
0 голосов
/ 26 мая 2020

Мне нужно получить данные из базы данных 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 l oop, он может быть выполнен до того, как будут получены все данные, верно? Некоторые запросы могут все еще выполняться

Итак, как я могу гарантировать, что мой массив с данными готов?

Когда такого рода данные используются для обновлений пользовательского интерфейса I на самом деле все это делается, поскольку пользовательский интерфейс подписан на мои "опубликованные" переменные, но в этом случае я хочу иметь возможность определять, когда ВСЕ ЗАПРОСЫ завершены и данные получены.

Как лучше всего это сделать? Следует ли мне использовать счетчик для проверки выполнения всех запросов и использовать обработчик завершения?

1 Ответ

1 голос
/ 26 мая 2020

Вы можете использовать DispatchGroup. Используйте функции enter() и leave(), чтобы решить, когда новая задача будет запущена и завершится sh. Затем используйте функцию notify(), чтобы делать все, что вам нужно, когда группа отправки пуста (что определяется путем подсчета действий входа и выхода).

...