Goal:
My goal here is to fetch initial data, update UI after I am sure all data is fetched, and continue observing changes immediately:
The Problem
I see two ways to do this:
- To use
getDatamethod and to fetch all data at once (bulky). This is ok cause I know I have fetched all data at once, and I can accordingly updateUIand continue listening for changes (CRUD).
The problem with this approach is that I can't just attach listener after, to listen to a for new additions (inserts), and wait for new items. It works differently (which makes sense cause I fetched data without being in sync with a database through listeners), and immediately after I attach the listener, I get its callback triggered as many times as how many items are currently in a root node. So I am getting most likely the same data.
So this seems like overkill.
- Second way to do this, is just to attach the listener, and get all data. But the problem with this is that I don't know when all data is fetched, cause it comes sequentially, one item by another. Thus I can't update UI accordingly.
Here are some code examples:
I am currently fetching all previous data with a getData method, like this:
func getInitialData(completion: @escaping DataReadCompletionHandler){
rootNodeReference.getData { optionalError, snapshot in
if let error = optionalError {
completion([])
return
}
if let value = snapshot.value,
let models = self.parseData(type: [MyModel].self, data: value) as? [MyModel]{
completion([MyModel](models.values))
}
}
}
As I said, with this, I am sure I have all previous data and I can set up my UI accordingly.
After this, I am interested in only new updates (updates, deletions, inserts).
And later I connect through listeners. Here is an example for a listener that listens when something new is added to a root node:
rootNodeReference.observe(DataEventType.childAdded, with: {[weak self] snapshot in
guard let `self` = self else {return}
if let value = snapshot.value,
let model = self.parseData(type: MyModel.self, data: value) as? MyModel{
self.firebaseReadDelegate?.event(type: .childAdded, model: model)
}
})
This would be great if with this listener I would somehow be able to continue only updates when something new is added.
Though, I guess option 2. would be a better way to go, but how to know when I have got all data through listeners?