'Is there a way to get an initial event when using firestore/angularfire collectionChanges() on an empty collection
I am using Firestore with AngularFire and am currently trying NgRx for a new feature. As recommended, I am using collectionChanges instead of collectionData, to only subscribe to the incoming changes instead of getting a whole update of the full data every time.
This works fine when there is data in the collection. Initially, I am getting a list of "added" events, and then "modified", "removed", and "added" as they are happening.
The problem is that when the collection is empty, I am not getting any event, so I cannot switch from loading to an empty view.
I would expect to receive an empty array of DocumentChanges at the initial load, but this does not happen. My current workaround is to listen to collectionData additionally and merge the first result to the collectionChanges subscriptions if it is empty.
This seems like an ugly hack. Is there a better/cleaner solution?
Solution 1:[1]
As recommended, I am using collectionChanges instead of collectionData, to only subscribe to the incoming changes instead of getting a whole update of the full data every time.
According to the official documentation regarding collectionChanges() function, it is said that:
The collectionChanges() function creates an observable that emits the changes on the specified collection based on the input query.
What is not specified there, is that it emits the changes on the specified collection (only if the collection exists).
This works fine when there is data in the collection. Initially, I am getting a list of "added" events, and then "modified", "removed", and "added" as they are happening.
That's the expected behavior since your collection already contains documents. So once you get the initial data, you can then later get all events as they occur.
The problem is that when the collection is empty, I am not getting any event, so I cannot switch from loading to an empty view.
It makes some kind of sense because when a collection in Firestore doesn't contain any documents, that collection doesn't exist at all. A collection will start to exist only when there is at least one document present. Please note that the collections in Firestore don't work like filesystem directories. There is no way you can create an empty collection. The collections are always tied to the documents they contain.
I would expect to receive an empty array of DocumentChanges at the initial load, but this does not happen.
To be honest it makes sense again since we cannot expect to get an event from a collection that actually doesn't exist.
My current workaround is to listen to
collectionData
additionally and merge the first result to thecollectionChanges
subscriptions if it is empty.
While your workaround will definitely work, I don't think it's the best option that you have.
This seems like an ugly hack. Is there a better/cleaner solution?
It's not ugly but it will most likely imply a lot of reads. So if your collection contains a lot of documents, you'll be billed with one read operation for each "added" document it exists in the initial event.
So in my opinion, there are two ways in which you can solve this.
The first one would be to always create a dummy document, so your collection will start to exist. Or, you can check if the collection is empty. How can you do that? Simply by performing a query and limit the results to one. Then check the size of the query document snapshot. In this way, you'll always know if the collection is empty or not. So knowing this, you can only use collectionChanges() if the collection contains at least a document. That being said, you'll have to pay a single document read for checking that. However, you'll still be charged with one document read, even if your query yields no results.
So no matter what the query returns, you'll always need to pay only one document read.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Alex Mamo |