I'm implementing a social media app, where I put a subcollection of "following" under each user. I want to check if the subcollection exists before I query the subcollection, or the app will crash for querying a nonexistent collection. Is there a way to check this?
Collections don't really "exist" in the way that you're thinking. They simply appear when the first document is created, and they disappear when the last document is removed. There is no operation to simply create or remove a collection like a folder in a filesystem, and there is not operation to check to see if a collection "exists". A query against a collection with no documents will not fail (unless it was rejected by a security rule).
The only thing you can really do is query the collection to see if it has any documents at all. You can limit the query to 1 document if you want to minimize costs.
Related
I was wondering if you could create a sub-collection from within flutter to firestore. I've heard you need to add manually add a document or something like that before you can access a sub-collection from flutter, but I wanted to know if there was a work-around.
Something like this-> Firebase.Firestore.instance.collection('groups').doc(groupID).collection('posts').add('')
without having to manually add a document first. Thanks
In Firestore (all client platforms, not just Flutter), both collections and subcollections don't "exist" in the console unless there is at least one document in it. If you want a subcollection to "exist", simply write a document to it.
When the last document is removed from a collection or subcollection, it ceases to "exist" in the console (after you reload it).
Collections are not really an "thing" in firestore. Documents are a thing, and they happen to be organized under collections. Your app should not depend on collections or subcollections existing - it should depends on documents being returned from queries on those collections.
See also:
Is possible to check if a collection or sub collection exists?
How to check if Cloud Firestore collection exists? ( querysnapshot)
In Dart/Flutter, how can I find out if there is no Collection in the Firestore database?
TL-DR
I have created a Flutter Firestore posts application. I want to present the user only new posts, which they didn't read yet.
How do I achieve that using Firestore query?
The problem
Each time a user sees a post, their id is added to the post views field.
Next time the user opens the app, I want to present only posts they didn't read yet.
The problem is that query array-not-contains is not supported. How do I achive that functionality?
You're going to have a real hard time with this because Firestore can only give you documents where you know something about the contents of that document. That's how indexes work - by recording data present in the document. Indexes don't track data not present in a document because that's basically an infinite amount of data.
If you are trying to track documents seen by the user, you would think to mark the document as "seen" using a boolean per user, or tracking the document ID somewhere. But as you can see, you can only query for documents that the user has seen, because that's the data present in the system.
What you can do is query for all documents, then query for all the documents the user has seen, then subtract the seen documents from all documents in order to get the unseen documents. But this probably doesn't scale in a way you'd like. (It's essentially the same problem with Firestore indexes not being able to surface documents without some known data present. Firestore won't do the equivalent of a SQL table scan, since that would be a lot of reads you'd have to pay for.)
You can kind of fake it by making sure there is a creation timestamp in each document, and record for each user the timestamp of the most recent seen document. If you require that the user must view the documents in chronological order, then you can simply query for documents with a creation timestamp greater than the timestamp of the latest document seen by the user. This is really as good as it's going to get with Firestore, since you can't query for the absence of data.
We have a collection in Google Firestore.
Can we add a document with data and a subcollection under this new document in one statement?
In one statement, no. Strictly speaking, most programming languages are going to require at least one statement for each document to write using the provided APIs.
In one batch, yes. You can simply do a batch write to create any two documents simultaneously. Parent documents and subcollections do not need to exist in order to create a nested document, so there is not even any requirement to create the parent document, if that's what you were wondering.
Also, you can't create a subcollection that doesn't "exist". It will exist when the first document is written, and disappear when the last document is deleted.
Subcollections in Firestore must reference a document within a collection. If this document is ever deleted, its subcollections remain. However, is it good practice to create subcollections underneath documents that never exist (never have existed, never will exist)? Is there any vulnerability in this pattern?
It doesn't really make any difference - it is neither "good" nor "bad". Do whatever suits your application. The data in subcollections can be queried regardless if the parent document exists or not, and creating or deleting that parent document doesn't affect the subcollection in any way.
In my application user gets to pick specific documents out of the list, for example: 1,5,8 from the list containing documents 1,2,3,4,5,6,7,8,9. When logged into the application next time, I want to first fetch all of the chosen documents (considering pagination, because the number of documents user picked could be very high), and then start fetching the remaining documents as the user finishes viewing picked documents by scrolling down the list.
As it turns out, available Firestore querying methods are not capable of skipping the specific documents.
My current idea:
Make single document references for the user-specific documents and fetch them.
Make single document references for the documents between the range of user-specific documents (From the example that would be documents number: 2,3,4,6,7).
After that start making 'big queries' for the remaining documents.
This looks like a working solution, but I'm sure that there is a better way to accomplish the goal, since what I've done is not asynchronous and very slow. Help is appreciated!
Firestore doesn't have any way to exclude specific documents from queries. You may only include them using some existing field values. If you already know the documents to fetch, you can just get() them individually.
It sounds like you are already able to work around these requirements. I don't believe you have any alternatives.