0

I'm a newbie to both Swift and Firebase, I don't Firebase is async connection and I don't know the best practice how to control the the program to wait for the return of data from Firebase and then proceed to next line.

Here is my code: I need to make two queries and once they were completed, then move on the the function prepareSelectedDftList, but the problem is the function is get called before Firebase return. Appreciated to give me some guidance how to fix it. Thank you.

        ref = Database.database().reference().child(dftNode)
        ref.observe(DataEventType.value, with: { (snapshot) in
            // need to consider the workshop is still empty or not?
            if snapshot.childrenCount > 0 {
                // get defect list
                for defect in snapshot.children.allObjects as! [DataSnapshot] {
                    let defectObj = defect.value as? [String: AnyObject]
                    let defectId = defect.key
                    let defectName = defectObj?["name"]
                    self.tmpDisplayDefectIdList.append(defectId)
                    self.tmpDisplayDefectNameList.append(defectName as! String)
                    self.tmpDefectSelected.append(0)
                }
            }
        })

        selectedDft = Database.database().reference().child(node)
        selectedDft.queryOrderedByKey().queryEqual(toValue: passInCompId).observe(.childAdded, with: { (snapshot) in
            for child in snapshot.children {
                let snap = child as! DataSnapshot
                let tmpkey = snap.key as String?
                self.selectedDftId.append(tmpkey!)
            }
            self.prepareSelectedDftList()
        })

1 Answers1

0

You need to do like this:

ref = Database.database().reference().child(dftNode)
       ref.observe(DataEventType.value, with: { (snapshot) in
           // need to consider the workshop is still empty or not?
           if snapshot.childrenCount > 0 {
               // get defect list
               for defect in snapshot.children.allObjects as! [DataSnapshot] {
                   let defectObj = defect.value as? [String: AnyObject]
                   let defectId = defect.key
                   let defectName = defectObj?["name"]
                   self.tmpDisplayDefectIdList.append(defectId)
                   self.tmpDisplayDefectNameList.append(defectName as! String)
                   self.tmpDefectSelected.append(0)
               }
           }

           selectedDft = Database.database().reference().child(node)
           selectedDft.queryOrderedByKey().queryEqual(toValue: passInCompId).observe(.childAdded, with: { (snapshot) in
               for child in snapshot.children {
                   let snap = child as! DataSnapshot
                   let tmpkey = snap.key as String?
                   self.selectedDftId.append(tmpkey!)
               }
               self.prepareSelectedDftList()
           })
       })

OR Call both in parallelly

var i = 0

ref = Database.database().reference().child(dftNode)
       ref.observe(DataEventType.value, with: { (snapshot) in
           // need to consider the workshop is still empty or not?
           if snapshot.childrenCount > 0 {
               // get defect list
               for defect in snapshot.children.allObjects as! [DataSnapshot] {
                   let defectObj = defect.value as? [String: AnyObject]
                   let defectId = defect.key
                   let defectName = defectObj?["name"]
                   self.tmpDisplayDefectIdList.append(defectId)
                   self.tmpDisplayDefectNameList.append(defectName as! String)
                   self.tmpDefectSelected.append(0)
               }
           }
           i = i + 1
           if i == 2{
               self.prepareSelectedDftList()
           }
       })

       selectedDft = Database.database().reference().child(node)
       selectedDft.queryOrderedByKey().queryEqual(toValue: passInCompId).observe(.childAdded, with: { (snapshot) in
           for child in snapshot.children {
               let snap = child as! DataSnapshot
               let tmpkey = snap.key as String?
               self.selectedDftId.append(tmpkey!)
           }
           i = i + 1
           if i == 2{
               self.prepareSelectedDftList()
           }
       })
Hitesh Surani
  • 12,733
  • 6
  • 54
  • 65
  • Hi IMHiteshSurani, thank you for your help. May I know why it works by just change the code sequence? is it related to closures and the process sequence will be the inner query will be finished first, then the outer query? – Mike Darwin Apr 14 '20 at 08:15
  • @MikeDarwin First things, I have just not change the sequence of code. Code snippet 1 access the data sequencially and Code snipest 2 access data paralelly from firebase – Hitesh Surani Apr 14 '20 at 09:03