Reputation: 236
So I am currently trying to get the number of "Posts" within my Firebase Database, but for some reason, it says that the amount equal to one (which is true) but then resets itself when calling "postNumber". I also want to keep the data in the array for later use so I kept it all in an array rather than reading straight off the Database and not storing any data at all.
viewDidLoad() Function
var postNumber = 0
override func viewDidLoad() {
super.viewDidLoad()
updateFeed()
print("PostNumber in ViewDidLoad: \(self.postNumber)") //equals 0
collectionView?.backgroundColor = .white
}
updateFeed Function
func updateFeed(){
let uid = FIRAuth.auth()?.currentUser?.uid
let ref = FIRDatabase.database().reference(fromURL: "https://firebaseio.com/")
ref.child("users").child(uid!).child("Posts").observe(.value, with: { (snapshot) in
for item in snapshot.children{
let snapshotValue = snapshot.value as? NSDictionary
var snapString = String(describing: item)
var snapInt = Int(snapString)
self.postCollection.append(snapString)
let firstName = (snapshot.value as! NSDictionary)["First Person"] as? String
print("SnapShot: \(snapString)") //gives proper data
self.postNumber = self.postCollection.count
print("PostNumber: \(self.postNumber)") //equals 1
print("PostSource: \(self.postCollection)")
}
})
print("Number of Posts (After Adding): \(self.postCollection.count)") //equals 0
collectionView?.reloadData()
}
Upvotes: 1
Views: 85
Reputation: 1038
To elaborate on the above answer, Firebase uses a completion handler or callback which allows you to do work on the data retrieved from the asynchronous call once it has been completed. In your example, because of the asynchronous operation, both of your print
commands are executed before Firebase returns from the asynchronous call. Any code executed outside the Firebase completion handler runs the risk of executing before the data has been retrieved.
I would review this Firebase doc, which talks about their asynchronous operations and callback (completion handlers).
https://firebase.google.com/docs/database/ios/read-and-write
Upvotes: 0
Reputation:
It doesn't actually reset itself. The problem is you're calling postNumber before Firebase has a chance to replace it with 1. Firebase queries work asynchronously, basically this means your code will continue to run while Firebase is fetching the results of your query.
An easy way to show this would be by replacing your first line with this. The didSet will run every time the value of postNumber changes. This will show you in exactly which order the commands are executed.
var postNumber = 0 {
didSet {
print(postNumber)
}
}
And if you're using postCollection to fill up your collectionView you can use
var postCollection = [String]() {
didSet {
collectionView?.reloadData()
}
}
You can leave the rest of your code as is, this should give you a basic understanding of what async is. With some googling you should be able to find elegant ways to deal with asynchronous code.
Upvotes: 1