0

I need to create calendar that displays data downloaded from three/four different documents from Firestore. I need to fill the array with that data and then display it. The code below shows how I'm dealing with three functions with escaping block. One is triggered after another.

    func getUserOrders(startDate: Timestamp, endDate: Timestamp){
    guard let userID = Auth.auth().currentUser?.uid else {return}
    orderBrain.returnWhenSomeneOrderedUser(userID: userID, startDate: startDate, endDate: endDate) { (calendar1) in
        self.orderBrain.returnWhenUserBoughtOrders(userID: userID, startDate: startDate, endDate: endDate) { (calendar2) in
            self.orderBrain.getOrdersFromArchive(userID: userID, startDate: startDate, endDate: endDate) { (calendar3) in
            self.fillEvents(event1: calendar1, event2: calendar2, event3: calendar3)
        }
      }
    }
}

After the last is completed I'm added downloaded values to an array.

    func fillEvents(event1: [CalendarEvent], event2: [CalendarEvent], event3: [CalendarEvent] ){

    self.models = event1 + event2 + event3
    self.reloadData()
}

The above code works but I'm wondering if there is a better more elegant solution when downloading data and filling an array from more than one escaping function. The problem with above code is that when sometimes it doesn't update data from Firestore (when user changes for ex. date)

Thank you Matt

Matt199
  • 264
  • 2
  • 18
  • 1
    You should look into using a `DispatchGroup` – EmilioPelaez Mar 05 '21 at 13:33
  • If that code is failing then there's something else wrong. A DispatchGroup will be useful, as @EmilioPelaez mentioned however, it's still the same asynchronous code at the core and functions in the same way, just better organized within the dispatch group. I would get the error in that code fixed first and then explore the Dispatch group. – Jay Mar 05 '21 at 19:01
  • For DispatchGroups, check out my answer [here](https://stackoverflow.com/questions/59744053/fill-an-array-through-a-nested-firebase-data-loop-swift/59759125#59759125) and [here](https://stackoverflow.com/questions/56606737/how-to-call-combine-multiple-completion-handlers-to-combine-data-to-one-new-arra/56611183#56611183) – Jay Mar 05 '21 at 19:04
  • Thanks @EmilioPelaez and @Jay. `DispatchGroup` is great when you downloading documents only once, unfortunately I need to listen for changes and those function need to be called whenever some field changes in Firestore. Using `DispatchGroup` in `snapshotListener` will trigger `dispatchGroup.leave()` and enter() won't be called whenever data will change in one of the collections in Firestore... – Matt199 Mar 09 '21 at 15:58
  • You may be misunderstanding how dispatch groups function. They are unrelated to the firebase asynchronous closures and can be used in conjunction with them to control the order in which data is loaded based on events firing. So you could for example, be observing a node and when an event occurs, create a dispatch group that loads additional data based on that event, and then executes a completion handler. – Jay Mar 10 '21 at 17:47

0 Answers0