【问题标题】:Using completion handlers for sequential querying Firestore collections使用完成处理程序对 Firestore 集合进行顺序查询
【发布时间】:2020-06-28 00:49:26
【问题描述】:

我正在通过下面的主要功能查询餐厅列表。然后我使用餐馆列表从另一个集合中获取他们的膳食计划列表:

MealplanCalls.getRestaurants(userId: userId) { (restaurantList, error) in
            if let error = error {
                self.showError(show: "Error", display: error)
            } else {
                var currentPlansArray = [Mealplan]()
                var restaurantIndex = 0
                while (restaurantIndex < restaurantList.count) {
                    MealplanCalls.getPlans(restaurantId: restaurantList[restaurantIndex]) { (mealplans, error) in
                        guard let mealplans = mealplans, mealplans.count > 0 else { return }
                        self.planArray.append(contentsOf: mealplans)
                        print("empty : \(self.planArray.count), \(self.planArray)")
                        if let error = error {
                            self.showError(show: "Error", display: error)
                        }
                        DispatchQueue.main.async {
                            self.planTable.reloadData()
                        }
                    currentPlansArray.removeAll()
                    restaurantIndex += 1
}
            }
        }

这是我获取餐厅列表的服务:

static func getRestaurants(userId : String, completionHandler : @escaping ([String], String?) -> Swift.Void) {
        let db = Firestore.firestore().collection("Restaurant_Data")
        var restaurantList = [String]()
        db.whereField("users", arrayContains: userId).getDocuments { (restaurantSnapshot, error) in
            if let error = error {
                completionHandler([], error.localizedDescription)
            } else {
                for document in restaurantSnapshot!.documents {
                    restaurantList.append(document.documentID)
                }
                completionHandler(restaurantList, nil)
            }
        }
    }

这是我获取膳食计划的地方:

static func getPlans(restaurantId : String, completion : @escaping ([Mealplan]?, String?) -> Void) {
        let db = Firestore.firestore().collection("Meal_Plans")
        db.whereField("restaurantId", isEqualTo: restaurantId).order(by: "hour", descending: false).getDocuments { (querySnapshot, error) in
            if let error = error {
                completion([], error.localizedDescription)
            } else {
                let mealplans = querySnapshot?.documents.compactMap { (queryDocuments) -> Mealplan in Mealplan(dictionary: queryDocuments.data(), mealplanId: queryDocuments.documentID, opened: false, menuItems: [MenuItems(menuItemName: "", menuItemQuantity: "")])!}
                completion(mealplans, nil)
            }
        }
    }

问题出在我的表格视图中,我只看到其中一个膳食计划重复了 planArray.count 次。我认为主要问题是我在哪里重新加载 tableview?

【问题讨论】:

    标签: swift google-cloud-firestore


    【解决方案1】:

    你可以使用 dispatchGroup 来解决这个问题

    MealplanCalls.getRestaurants(userId: userId) { (restaurantList, error) in
                if let error = error {
                    self.showError(show: "Error", display: error)
                } else {
                    var currentPlansArray = [Mealplan]()
                    var restaurantIndex = 0
                    let group = DispatchGroup()
                    
                    while (restaurantIndex < restaurantList.count) {
                        group.enter()
                        MealplanCalls.getPlans(restaurantId: restaurantList[restaurantIndex]) { (mealplans, error) in
                            guard let mealplans = mealplans, mealplans.count > 0 else { return }
                            self.planArray.append(contentsOf: mealplans)
                            print("empty : \(self.planArray.count), \(self.planArray)")
                            if let error = error {
                                self.showError(show: "Error", display: error)
                            }
    
                        group.leave()
                        currentPlansArray.removeAll()
                        restaurantIndex += 1
                   }
                }
                    
                    
                    group.notify(queue: DispatchQueue.main, execute: {
    
                      self.planTable.reloadData()
                    })
                  
            }
    }
    

    【讨论】:

    • 谢谢,我尝试了各种不同的调度组,但最终还是得到了一个空数组或重复的数组对象。
    • 在这里使用 sempahore 会更有意义吗?
    • 如果您的问题本质上是技术问题,而不是特定于代码的问题,您可以在此处 [1] 寻求免费的 Firebase 支持。 [1]firebase.google.com/support/troubleshooter/contact?authuser=0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 1970-01-01
    相关资源
    最近更新 更多