为什么我的firebase数据库没有等待更新值

时间:2017-03-29 09:30:03

标签: ios swift multithreading firebase firebase-realtime-database

所以我对线程很陌生,而且我整天都在阅读它。出于某种原因,虽然数据在其他代码执行之前没有加载

基本上我需要所有具有键["无论什么"]的值被填充到数组中,这在其他地方有效,因为我不需要先加载它。所以我已经检查并仔细检查了我正在更新的密钥确实存在并且我提取的密钥确实存在可能不是值但是密钥确实存在。

问题是代码快速通过该方法。如何使主线程等待,直到我的firebase已经加载了我在下面尝试过的数据,但它似乎没有工作

这是我的代码

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) -> Void in
        print("Ok button tapped")
    })

    let yesButton = UIAlertAction(title: "Yes", style: .default, handler: { (action) -> 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)
}

以下函数更新值OpposingUsername并显示

func updateBet(_ index: Int, completion: @escaping (_ something: String?) -> 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)
    }


}

好的,所以使用这个更新的代码,它会删除我之前的逻辑错误,但现在应用程序挂起在我的waitAlertViewController上。不知道为什么。它确实更新了firebase数据库中的赌注,所以我知道它的工作和运行代码,但它就像从未完成所有。对不起bibscy我明白你的意思了

完成处理程序一旦你更好地理解它们就非常强大

1 个答案:

答案 0 :(得分:2)

 //Notice that I made `result: String?` optional, it may or may not have a value.    
 func getOpoosingUserNames(_ username: String,_ index: Int, completion: @escaping (_ result: String?) -> 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
        let username = value?["username"] as? String ?? ""
        self.userName = username

        // ...


        self.datRef.child("Bets").observe(.childAdded, with: { snapshot in
            //
            // this is the unique identifier of the bet.  eg, -Kfx81GvUxoHpmmMwJ9P

            let betId = snapshot.key as String
            guard let dict = snapshot.value as? [String: AnyHashable] else {
                print("failed to get dictionary from Bets.\(self.userName)")
                return
            }
            if let show = dict["Show"] as? String {

                let opposingUser = dict["OpposingUsername"] as? String
                    self.opposingUserNames.append(opposingUser!)
            }



             completion(opposingUserNames)
        })
    }) { (error) in
        print(error.localizedDescription)
    }

}



    //update the be
   func updateBet(_ index: Int, completion: @escaping (_ something: [String]?) -> 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"]

    //store the values received from Firebase in let valueOfUpdate and pass this
  // constant to your completion handler completion(valueOfUpdate) so that you can use this value in func 
   //tableView(_ tableView:_, didSelectRowAt indexPath:_)
          let valueOfUpdate =  self.datRef.child("Bets").child(self.tieBetToUser[index]).updateChildValues(values)



     completion(valueOfUpdate)
  }) { (error) in
    print(error.localizedDescription)
  }


}


  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) -> Void in
        print("Ok button tapped")
    })

    let yesButton = UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
        //take away that bitches money
        self.takeAwayMoney(self.amountBets[indexPath.row])

        //then delete that cell and do another pop up that says successful
        // check if value is yes or no in the database
        self.updateBet(indexPath.row, completion: {(result: String) in


  guard let resultReceivedInupdateBet = result, else {
    print("result of updateBet() is \(result)")
}
         print("If you see this print, database was updated")

  //calling this method with the indexPath.row clicked by the user
     self.getOpoosingUserNames(self.userName, indexPath.row, completion: { (result: [String]) in


 guard let resultReceivedIngetOpoosingUserNames = result{
      print("result of getOpoosingUserNames is \(result)")
 }
     print("If you see this print, you received a value from db after calling getOpoosingUserNames and that value is in \(result) ")

  //result is not nil, resultReceivedIngetOpoosingUserNames has the same value as result.

 }//end of self.getOpoosingUserNames

        self.checkForNo(indexPath.row)
        self.amountBets.remove(at: indexPath.row)
        self.tableView.reloadData()
        print(self.opposingUserNames)

        let successController = UIAlertController(title: "Success", message: "You have made a bet with " + self.opposingUserNames[indexPath.row], 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
        self.opposingUserNames.remove(at: indexPath.row)

    })

    alertController.addAction(okButton)
    alertController.addAction(yesButton)
    present(alertController, animated: true, completion: nil)
 }