Данные загружаются из Firebase асинхронно, поскольку может потребоваться некоторое время, чтобы выйти из сервера / сети. Ваш основной код приложения продолжает работать, пока данные загружаются. Затем, когда данные будут доступны, вызывается ваш обработчик завершения.
По этой причине любой код, который требует данных из базы данных, должен быть внутри обработчика завершения или вызываться оттуда. Если вы поместите его куда-либо еще, вы не будете уверены, что данные будут загружены к тому времени, когда это потребуется коду.
Так, например:
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)
}
Внутри обратного вызова не используется self.userWeight
, поэтому он получает доступ к значению из базы данных, как только он загружен.
Если вы хотите, вы также можете определить свой собственный обработчик завершения, который вы затем вызываете из обработчика завершения Firebase, или используете группу рассылки. Некоторые примеры этого см .:
Edit:
Просто обратите внимание, что обновления пользовательского интерфейса в закрытии Firebase вызываются в главном потоке. Так, например, если вы загружаете источник данных tableView внутри замыкания, вы также можете вызывать tableView.reloadData () внутри замыкания, не используя группу диспетчеризации или другой поток.