How does Firestore document snapshot work? - firebase

when a new document is added, snapshot fetches all the documents including the new ones or only the newly added ones ? If it fetches all the documents every time then it will add to the billing cost. How to get around this problem ?
StreamBuilder(
stream:Firestore.instance
.collection('chat')
.orderBy('timeStamp', descending: true).snapshots(),
builder: (context, streamSnapshot) {}
);

While your snapshots() listener stays active, the server actively monitors for changes that are relevant to your listener. When there are such changes it only sends you new documents, or documents that were changed, to your client. The client then merges those updates with its local data, and presents you with a new complete QuerySnapshot.

According to the official doc : Here
There are two ways to retrieve data stored in Cloud Firestore. Either of these methods can be used with documents, collections of documents, or the results of queries:
Call a method to get the data.
Set a listener to receive data-change events.
When you set a listener, Cloud Firestore sends your listener an initial snapshot of the data, and then another snapshot each time the document changes.
You can get an array of the document snapshots by using the docs property of a QuerySnapshot. After that you'll have to loop through getting the data of the doc snapshots looking for your doc.
OR if you don't actually need the full QuerySnapshot, you can apply the filter using the where function before calling get on the query object
These are the most efficient way to get documents.

Related

fetch limited number of document from Firestore in Flutter

I'm trying to fetch a certain number of document for viewing it in a limit view table, for example 50 elements at the time, whenever the user clicks next it loads the next 50 element form the Firestore and shows it in the table, in order to reduce the data loaded from the firebase and not to slow down the application, since there may be millions of documents stored in the Firestore,
I've tried this solution but is it the best practice?
Thanks.
vehiclesCollection.snapshots().skip(10).take(10).map(
(event) {
print('some logic');
},
);
According to the Firebase docs and FlutterFire docs batching is possible!
It looks like this:
FirebaseFirestore.instance
.collection('users')
.limit(50)
.get()
.then(...);
In order to make it a working pagination you could add startAfterDocument to your query and give as parameter for each request the last element from the previously returned collection:
FirebaseFirestore.instance
.collection('users')
.limit(50)
.startAfterDocument(lastDocument)
.get()
.then(...);

Update document value in Firestore Cloud with Flutter, having only a unique key value of such document

I'm new to Cloud Firestore but already made some CRUD operations but now I'm really stuck with this thing.
Each document inside the 'tiposFrota' collection has a key 'nome:' with a unique value, no document will have the same value for the 'nome:' key.
The problem is, whenever the user adds another 'Truck' to some other collections I need to increment the value of 'qtde:' by one, and when they remove 'Truck' the program will increment the number by -1, working as a counter.
I managed to create an operation to update a key value, but only when you have the document id, but in this case the id is autogenerated because they may add or remove standard values from the 'tiposFrota' collection.
FirebaseFirestore.instance
.collection('controladores')
.doc('contadores')
.update({'numFrota': FieldValue.increment(1)}),
I'm really stuck with this, if anyone could please help.
Thanks!
Woah, managed to find a solution by myself, this post Get firestore collections based on values in array list in flutter.
Since the 'nome:' value is unique for each document inside the 'tiposFrota' collection I can use the .where statement as a filter for said document, get the snapshot with all the documents (but only getting one, obviously) and use the 'forEach' method to create a function using the '.id' parameter when calling the document.
FirebaseFirestore.instance
.collection('tiposFrota')
.where('nome', isEqualTo: carMake)
.get()
.then((querySnapshot) {
querySnapshot.docs.forEach((element) {
FirebaseFirestore.instance
.collection('tiposFrota')
.doc(element.id)
.update({
'qtde': FieldValue.increment(1)});
});
}),

How to fetch only documentIDs [Firebase-Flutter]

In my firebase's database I have Users and every user has multiple stores that he ordered from and every store has multiple orders.
To fetch all the orders for specific store I write the following query and it works fine.
QuerySnapshot result = await Firestore.instance
.collection('users')
.document(userID)
.collection('Stores').
document(storeID).getDocuments();
However, I do not need that. I just need the stores that the user ordered from. In other words, I need list of storeIDs for specific user.
Here is my code but it doesn't work.
QuerySnapshot result = await Firestore.instance
.collection('users')
.document(userID)
.collection('Stores').getDocuments();
I just want the IDs
It's not possible with web and mobile clients to get only the IDs without the entire set of documents and their data. If you want a list of all IDs for all documents in a collection or subcolleciton, you're going to have to query that collection as you currently show in the second example. You can easily extract the IDs from the returned documents in the QuerySnapshot. But you are still paying the cost of a document read for each document in the collection, and waiting for all of their contents to transfer.
If you want, you can create your own backend endpoint API to use a server SDK to query for only the IDs, and return only the IDs, but you are still paying a document read for document.

Is there a way to sort a collection when creating random documents inside a collection?

Is there a way to use orderBy( ) when creating random documents inside a collection such that the newly created one will always come after the previous one.
In my case the collection is called ‘Chats’ and documents are created at random and I loop through them to reveal messages. I want an order where newly created documents will always come after the previous ones. how do I achieve this?
firestore
.collection(InterviewsInformation)
.document(InterviewID)
.collection('Chat')
.add({
'MessageSender': MessageSender,
'MessageText': messageText,
});
I also tried sorting the collection by using a timestamp
firestore
.collection(InterviewsInformation)
.document(InterviewID)
.collection('Chat')
.add({
'MessageSender': employer['EmployerName'],
'MessageText': messageText,
'CreatedAt': FieldValue.serverTimestamp()
});
firestore
.collection(InterviewsInformation)
.document(InterviewID)
.collection('Chat').orderBy("CreatedAt", descending: true) ;
still doesn't work messages appear at random, can someone help?
Turns out that documents wont be created by random in the cloud firestore but your query in the stream builder can help show them in a sorted order
stream: firestore
.collection(InterviewsInformation)
.document(InterviewID)
.collection('Chat').orderBy('CreatedAt')
.snapshots(),

Access n-th document in Firestore with Flutter

I first want to determine the length of my collection (i.e. how many documents are in my collection?) and then randomly grab one of the documents and display certain fields in it.
In my Scaffold I have the following StreamBuilder so far:
StreamBuilder(
stream: _wordsFoods.snapshots(),
builder: (context, snapshot){
return _buildList(context, snapshot.data.documents);
}
)
_buildList returns the length of the collection "words":
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
return Center(child: Text(snapshot.length.toString()));
}
But how do I now say that I want the (e.g.) second document in my collection? How do I connect it with a query, so I can say I want a certain field within the second document of my collection?
There is no built-in count operation in Cloud Firestore. To determine the number of documents, you either have to retrieve all of them, or keep a separate counter. Since retrieving all documents to determine a number is highly wasteful of bandwidth, most developers go for the second option where they implement a counter field in a separate document in their database, and then update that on every add/delete operation.
There also is no operation to get a document at a certain offset in the client-side SDKs for Firestore. And while the server-side Admin SDKs do offer an offset() method, this one under the hood actually reads all documents that you're telling it to skip. So while it saves on bandwidth for those document, they are still read and charged to your quota.
To efficiently retrieve a random document from Firestore, have a look at Dan's answer here: Firestore: How to get random documents in a collection

Resources