title: Why is my firebase database not waiting to update values
body: <p>So I am really new to threading and I've been reading up on it all day. For some reason though the data isn't loading before other code executes </p>
  
  <p>Basically I need all the values that have a key ["whatever"] to be filled into an array, which works in other places because I don't need to load it first. So i have checked and double checked the keys that I am updating do exist and the keys I am extracting do exist maybe not the values yet but the keys do. </p>
  
  <p>The problem is the code goes to fast to through the method. How would I make the main thread wait untill my firebase has loaded the data I have tried it below but it does not seem to be working</p>
  
  <p>here is my code</p>
  
  <pre><code>func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      let alertController = UIAlertController(title: "Accept Bet", message: "Match the bet of " + amountBets[indexPath.row], preferredStyle: .alert)
  
      let okButton = UIAlertAction(title: "No", style: .default, handler: { (action) -&gt; Void in
          print("Ok button tapped")
      })
  
      let yesButton = UIAlertAction(title: "Yes", style: .default, handler: { (action) -&gt; Void in
          // let them know to wait a second or the bet won't go through
          var waitController = UIAlertController(title: "Please Wait", message: "You must wait for the bet to go through", preferredStyle: .alert)
  
          self.present(waitController, animated: true, completion: nil)
          //take away that bitches money
          self.takeAwayMoney(self.amountBets[indexPath.row], completion: { (result: Bool?) in
  
              guard let boolResult = result else {
                  return
              }
  
              if boolResult == true {
                  self.updateBet(indexPath.row, completion: {(result: String?) in
  
  
  
  
  
                      guard let resultRecieved = result else {
                          return
                      }
                      print(self.opposingUserNames)
                      //let delayInSeconds = 7.0 // 1
                      //DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) { // 2
                      self.dismiss(animated: true, completion: nil)
                      let successController = UIAlertController(title: "Success", message: "You have made a bet with " + self.opposingUserNames!, preferredStyle: .alert)
                      let okButt = UIAlertAction(title: "Ok", style: .default, handler: nil)
                      successController.addAction(okButt)
                      self.present(successController, animated: true, completion: nil)
                      //lastly delete the opposing UserName
                      print(self.opposingUserNames)
                      self.amountBets.remove(at: indexPath.row)
                      self.tableView.reloadData()
                      print("Second")
                      print(self.opposingUserNames)
                      //}
  
                  })
              } else {
                  return
              }
  
          })
  
          //then delete that cell and do another pop up that says successful
          // check if value is yes or no in the database
  
  
      })
  
      alertController.addAction(okButton)
      alertController.addAction(yesButton)
      present(alertController, animated: true, completion: nil)
  }
  </code></pre>
  
  <p>The below function updates the values OpposingUsername and show</p>
  
  <pre><code>func updateBet(_ index: Int, completion: @escaping (_ something: String?) -&gt; Void) {
      let userID = FIRAuth.auth()?.currentUser?.uid
      datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
          // Get user value
          let value = snapshot.value as? NSDictionary
          // ...
  
  
          self.datRef.child("Bets").observe(.childAdded, with: { snapshot in
              //
              // this is the unique identifier of the bet.  eg, -Kfx81GvUxoHpmmMwJ9P
              guard let dict = snapshot.value as? [String: AnyHashable] else {
                  print("failed to get dictionary from Bets.\(self.userName)")
                  return
              }
              let values = ["OpposingUsername": self.userName,"Show": "no"]
  
  
              self.datRef.child("Bets").child(self.tieBetToUser[index]).updateChildValues(values)
              // now get the opposing username which is just the Username registered to that specific bet
              self.datRef.child("Bets").child(self.tieBetToUser[index]).observe(.childAdded, with: { snapshot in
                  guard let dict2 = snapshot.value as? [String: AnyHashable] else {
                      return
                  }
                  let userNameOfOtherPlayer = dict2["Username"] as? String
                  self.opposingUserNames = userNameOfOtherPlayer!
                  completion(self.opposingUserNames)
              })
  
  
          })
  
      }) { (error) in
          print(error.localizedDescription)
      }
  
  
  }
  </code></pre>
  
  <p>ok so with this updated code it cuts out the logic errors I had earlier, but now the app hangs on my waitAlertViewController. Not sure why. it does updated the bet in the firebase database so I know its working and running that code but its like never completing it all. sorry bibscy I see what you mean now</p>
  
  <p>completion handlers are pretty powerful once you understand them better</p>