0

I have label and data from Firebase. I need to get the data, count it and update Label. But I have problem. I get the data later than I start counting it.

 let uid = Auth.auth().currentUser?.uid
        let ref = Database.database().reference()
        ref.child("users").child(uid!).child("weight").observe(.value) { (snapshot) in
            self.userWeight = snapshot.value as! Float
            print(self.userWeight)
        }

Than I should count it and display.

self.maxAmountOfWater = (self.userWeight * 4) / 100
maxWaterLabel.text = String(maxAmountOfWater)

Value of Label is 0 because I fetch data slow. I do it all in viewDidLoad

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Stormios
  • 127
  • 1
  • 8

1 Answers1

1

Data is loaded from Firebase asynchronously, since it may take some time to come down from the server/network. Your main application code continues to run while the data is being loaded. Then once the data is available, your completion handler is called.

For this reason, any code that requires data from the database, must be inside the completion handler, or called from there. Putting it anywhere else makes it uncertain that the data will have loaded by the time the code needs it.

So for example:

let uid = Auth.auth().currentUser?.uid
let ref = Database.database().reference()
ref.child("users").child(uid!).child("weight").observe(.value) { (snapshot) in
    self.userWeight = snapshot.value as! Float
    print(self.userWeight)

    self.maxAmountOfWater = (self.userWeight * 4) / 100
    maxWaterLabel.text = String(maxAmountOfWater)
}

Not the use of self.userWeight is inside the callback, so it has access to the value from the database as soon as it's loaded.

If you want you can also define your own completion handler, that you then call from within the Firebase completion handler, or use a dispatch group. For some examples of this, see:

Edit:

Just a note that UI updates within a Firebase Closure are called on the main thread. So for example, if you load a tableView dataSource within the closure, you can call tableView.reloadData() within the closure as well without having to use a dispatch group or other thread.

Jay
  • 34,438
  • 18
  • 52
  • 81
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807