title: Handler gets called early before for loop has finished processing Firebase snasphot in swift, why?
body: <p>I need some help, I have the following code which is part of function that queries and returns a <code>snapshot</code> of user data from <code>Firebase</code>. I am trying to loop through the <code>snapshot</code> passing it to a helper <code>filterDiscoveredUserByPreferences</code> method that assists in filtering in/out then it is suppose to be adding the object to an array so that it can be passed back via a <code>handler</code>.</p>
  
  <p>The issue is that my <code>handler</code> gets called too early way before the <code>for</code> loop has finished with the snapshot returned from <code>Firebase</code>. I have tried using <code>distpatchQueue</code> but that didn't work.</p>
  
  <pre><code>self.getUsersAtVenueHandle = self.REF_USERS.observe(.value, with: { (snapshot) in
  
                      guard let usersSnapshot = snapshot.children.allObjects as? [DataSnapshot] else { return }
  
  
                          for user in usersSnapshot{
                              // Code here to get all values from ‘user’ snapshot the create User object
  
                              let user = User(uid: uid, dictionary: dictionary)
  
                              if user.discoverable == true &amp;&amp; user.uid != Auth.auth().currentUser?.uid {
  
                                  self.filterDiscoveredUserByPreferences(discoveredUser: user, handler: { (success) in
  
                                      if success {
                                          users.append(user)
                                      }
  
                                  })//filterDiscoveredUserByPreferences
  
                              }//end if
  
                          }//end for
  
                          //handler gets called before for loops has finished processing the entire snapshot
  
                          handler (users, true)
                          users.removeAll()
  
  
                  }, withCancel: { (error) in
                      print(error)
  
                  })//end Firebase call
  </code></pre>
  
  <p>Function: filterDiscoveredUserByPreferences</p>
  
  <pre><code>func filterDiscoveredUserByPreferences(discoveredUser: User, handler: @escaping (Bool) -&gt; ()){
  
      let discoveredGender = discoveredUser.gender
      let discoveredPrefs: [String : Any] = discoveredUser.discoveryPrefs
      let discoveredPreferMen = discoveredPrefs["men"] as? Bool
      let discoveredPreferWomen = discoveredPrefs["women"] as? Bool
  
      var discoveredPreferredGender: String?
  
      switch (discoveredPreferMen, discoveredPreferWomen) {
  
      case (true, true):
          discoveredPreferredGender = "both"
  
      case (true, false):
          discoveredPreferredGender = "female"
  
      case (false, true):
          discoveredPreferredGender = "male"
  
      case (false, false):
          discoveredPreferredGender = "not discoverable"
  
      default:
          break
      }//end switch
  
  
      getUserInfo(forUserId: (Auth.auth().currentUser?.uid)!) { (user) in
  
          let myGender = user.gender
          let myDiscoveryPrefs: [String : Any] = user.discoveryPrefs
          let myPreferMen = myDiscoveryPrefs["men"] as? Bool
          let myPreferWomen = myDiscoveryPrefs["women"] as? Bool
  
  
          switch (myPreferWomen, myPreferMen) {
  
          case (true, true): //both
  
              switch myGender {
  
              case "male":
  
                  switch(discoveredPreferredGender){
  
                  case "male":
                      handler(true)
  
                  case "female":
                      handler(false)
  
                  case "both":
                      handler(true)
  
                  case "not discoverable":
                      handler(false)
  
                  default:
                      break
  
                  }//end switch
  
              case "female":
  
                  switch(discoveredPreferredGender){
  
                  case "male":
                      handler(false)
  
                  case "female":
                      handler(true)
  
                  case "both":
                      handler(true)
  
                  case "not discoverable":
                      handler(false)
  
                  default:
                      break
  
                  }//end switch
  
              default:
                  break
  
              }//end switch
  
  
  
          case (true, false)://female only
  
              if discoveredGender == "male"{
                handler(false)
              } else {
  
                  switch(discoveredPreferredGender){
  
                  case "male":
                      handler(true)
  
                  case "female":
                      handler(false)
  
                  case "both":
                      handler(true)
  
                  case "not discoverable":
                      handler(false)
  
                  default:
                      break
  
                  }//end switch
  
              }//end else
  
          case (false, true): //male only
  
              if discoveredGender == "female"{
                  handler(false)
              } else {
  
                  switch(discoveredPreferredGender){
  
                  case "male":
                      handler(true)
  
                  case "female":
                      handler(false)
  
                  case "both":
                      handler(true)
  
                  case "not discoverable":
                      handler(false)
  
                  default:
                      break
  
                  }//end switch
  
              }//end else
  
          case (false, false): //none
  
              handler(false)
  
          default:
              break
          }
  
  
      }//end getLoggedinUserDetails
  
  
  }//end fun
  </code></pre>
  
  <p>Func getUserInfo</p>
  
  <pre><code>func getUserInfo(forUserId: String, currentUserHandler: @escaping (_ currentUser: User) -&gt; ()){
  
      REF_USERS.child(uid).observe(.value, with: { (snapshot) in
  
          guard let dict = snapshot.value as? [String: Any] else { return }
  
          let user = User(uid: uid, dictionary: dict)
  
          currentUserHandler(user)
  
      }) { (error) in
          print(error)
      }
  
  }//end func
  </code></pre>