Firebase является асинхронным, и данные, возвращаемые из Firebase, действительны только в замыкании, следующем за функцией. Кроме того, код работает быстрее, чем inte rnet:
databaseRef.child("repos").queryOrderedByValue().observe(.childAdded) { (snapshot) in
//Firebase data is valid here but takes time to return from Firebase
}
//any code following the closure will run *before* the code in the closure.
Существует несколько опций
1) Считывание данных по .value, повторение заполнения массива
databaseRef.child("repos").queryOrderedByValue().observeSingleEvent(of: .value, with: { snapshot in
let allChildNodes = snapshot.children.allObjects as! [DataSnapshot]
for child in allChildNodes {
//create repoObject
self.repoArray.append(repoObject)
}
//reload your tableView or whatever you want to do with the array
}
2) Использование событий .value всегда запускается после .childAdded событий
var initialRead = true
func readTheRepos() {
let reposRef = self.ref.child("repos")
reposRef.observe(.childAdded, with: { snapshot in
//create repoObject
self.repoArray.append(repoObject)
if self.initialRead == false {
print("a new repo was added") //executes only after the initial read of all repos
}
})
reposRef.observeSingleEvent(of: .value, with: { snapshot in
print("inital load has completed and the last repo was read")
self.initialRead = false
})
}
3) Вести подсчет общего количества репо в узле репо в другой узел и сравните его, так как репозитории читаются через .childAdded
totalRepoCount = //get this from another node
currentCount = 0
reposRef.observe(.childAdded, with: { snapshot in
//create repoObject
self.repoArray.append(repoObject)
currentCount += 1
if currentCount == totalRepoCount {
//last repo was read
}
})