Firebase Read Operation Calculation - flutter

When I use .collection().doc() and specify a document id. Resulting in getting only one document from the collection, does this operation count as one read or as reading all of the documents in the firestore database?
StreamBuilder(
stream: firestore
.collection('users')
.doc(auth.currentUser!.uid)
.snapshots(),
Additional Question: The .where() query reads all the documents in the collection right? So the total reads is not the amount of documents I get as a result of the query but the total amount of documents in the collection? Thank you.

You are only charged for the documents that you read from/on the server. Since you only read one document, it's charged as one read (plus any charges for the bandwidth required to transfer the data).
A query does not read all documents in a collection, but instead uses one or more indexes to determine what documents to read. You are not charged explicitly for those index reads, unless there are no results for a query: in that case you get charged for one document read.

Related

Difference between .where() and .doc() related to number of reads

If I get a document by .collection('users').where('uid', isEqualTo, widget.uid) or by .collection('users').doc(widget.uid) will I read the database the same number of times?
You are charged one read for every document that matches your query when it is executed. It does not matter how you make that query - what matters is the number of documents returned to the app.
If your where query returns exactly one document, then it is not any different in price or performance than one using doc.
The former returns a QueryFieldFilterConstraint while the latter returns a DocumentReference. The DocumentReference is preferable because it can be used to write, read, or listen to the location.
Naturally, a query must read every id in the referenced collection (this is probably indexed) while a reference points to a single id. In terms of pricing, aggregateQueries documentation is actually returning a page not found error at the moment?
See Understand Cloud Firestore billing
For aggregation queries such as count(), you are charged one document
read for each batch of up to 1000 index entries matched by the query.
For aggregation queries that match 0 index entries, there is a minimum
charge of one document read.
For example, count() operations that match between 0 and 1000 index
entries are billed for one document read. For a count() operation that
matches 1500 index entries, you are billed 2 document reads.

Firestore pricing for `.get()` on a full collection without invoking `.data()`

I have a collection with thousands of records. When I perform .get() on the full collection, the query results seem to occupy (relatively) lower amount of memory which indicates that all the data isn't contained in the result set and we do a .data() to fetch the document.
So does that indicate that I am only billed for one document read for a .get() on full collection? Or am I billed for the total no. of documents contained in the result of the .get() (even if I don't run the .data() on snap.docs)?
I billed for the total no. of documents contained in the result of the .get()
Yes, you are charged for number of documents returned by your query. (Total number of docs in the collection in this case since you are fetching whole collection)
Even if I don't run the .data() on snap.docs
When you use get(), you've already queries required documents. .data() just returns data from the snapshots received.

Firestore sub documents read pricing

Firestore if I read a collection and the collection contains 100 documents then is firebase calculate it as 100 read operation or 1 read operation?
If my 1 document contains another 2 collections and each sub collection contains 10 docs then How much will be the total read count in this case?
if it counts subcollection and it doc separately then Firestore is very very high pricing
If you read all documents from a collection that contains 100 documents, then you're reading 100 documents. So you'll be charged for 100 document reads.
If you're reading documents from subcollections, then there too: you'll be charged for each document you read.
If you're struggling to find a data model that strikes a balance between a flexible structure and limiting the number of reads you need, I recommend watching the Getting to know Cloud Firestore video series, specifically these episodes:
What is a NoSQL Database? How is Cloud Firestore structured?
Cloud Firestore Pricing
How to Structure Your Data

Firestore | Why do all where filters have to be on the same field?

Apparently Firestore does not not support queries with range filters on different fields, as described here:
My question is, WHY?
HOW can I query by time and location for example:
Firestore.instance.collection('events')
.where("eventTime", isGreaterThanOrEqualTo: DateTime.now().millisecondsSinceEpoch)
.where("eventLocation", isGreaterThan: lesserGeopoint)
.where("eventLocation", isLessThan: greaterGeopoint)
.where("eventStatus", isEqualTo: "created")
.orderBy('eventLocation', descending: false)
.orderBy('eventTime')
.snapshots(),
(Example from Flutter App written in Dart)
I receive the following Error:
All where filters other than whereEqualTo() must be on the same field. But you have filters on 'eventTime' and 'eventLocation', null)
I don't understand how this is not supported and how to solve queries like this?
Any help is appreciated :-)
Thanks,
Michael
Cloud Firestore gives a strong performance guarantee for any read operations it allows: the time a read operation takes depends on the number of items you're reading, not on the number of items in the collection. This is a quite unique performance guarantee, since it means that your queries will take the same amount of time when you have 1 million users as when you have 1 billion users.
Firestore only offers query operations for which it can maintain this performance guarantee. This is the main reason for the limitations you may find in the Firestore query API.
To work around the limit, you'll typically perform the filtering, and ordering on the primary field in the query, and then sort on the secondary field client-side
If you'd like to learn more about Firestore's query capabilities and limitations, I highly recommend watching How do queries work in Cloud Firestore? and the rest of the Get to Know Cloud Firestore video series.
Also see:
Firestore order by two fields
Firestore order by two fields in one query
Have you had a read through the page on indexes, which describes how some compound queries can be supported, and how composite indexes can be created and used?

Firestore - Delete Documents without Read first

Is there a way to mass delete documents in a Collection without getting charged for a 'read' first?
Let's say I have a collection with 1000 documents. I decide I want to delete every document that's older than 1 day. I could use a Query to return a QuerySnapshot that returns [300] documents (DocumentReference). I don't need to read the documents contents (DocumentSnapshot), I just need to delete them.
From what I understand from the pricing documentation, because I returned a QuerySnapshot first, it will charge me for 300 reads, then 300 deletes. It doesn't delineate between "reading" a DocumentReference vs. "reading" data in a DocumentSnapshot.
Is there any way to avoid the 300 reads? I can understand that getting back these 300 documents involves effort on Firestore's end to figure out that appropriate subset of documents. But the arbitrary charge of a read no matter if you actually try to get document data (DocumentSnapshot) or not (e.g. just a DocumentReference to delete) seems like it should be possible to avoid.
To delete a document you must have or create a DocumentReference to that document. This requires that you know its complete and exact path to the document.
If you want to delete documents that match a certain condition without already knowing their paths, you will first need to query for those documents to determine those paths/DocumentReferences. This involves reading them. There is now way to avoid this at the moment.