fetch limited number of document from Firestore in Flutter - firebase

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(...);

Related

Firebase Query in Flutter Not Returning Results

I have 2 queries in my flutter app that reference the same information in firebase. One is filtered by the user's id and the other is filtered by the patient's id. Both queries work but only the query that is filtered by uid works with an orderby. Why isn't the second query working?
Query filtered by user id
FirebaseFirestore.instance
.collection('alerts')
.where('access', arrayContains: FirebaseAuth.instance.currentUser.uid)
.orderBy('createdAt', descending: true)
.snapshots(),
Query filtered by patient ID
FirebaseFirestore.instance
.collection('alerts')
.where('patientId', isEqualTo: patient.id)
//.orderBy('createdAt', descending: false)
.snapshots(),
I've commented out the orderBy in this query because it causes it to not return any results. Without using the orderBy I get the results I want just not in the order I want them.
The Alerts have a field called 'access' that contains user ids if that alert should be associated with that user. The 'patient id' on Alerts relates the alert to a specific patient.
The first query returns all alerts that should be viewed by the user.
The second query returns just the alerts for a specific patient.
You need to create indexes for both queries in your Firebase.
Coming back to this because I actually ended up fixing it. Like the other user mentioned I needed to create indexes in firebase in order for this to work. So I went to firebase created an index for my alerts collection and added patientID and creationDate both as descending to an index. Saved that index, waited for it to post to firebase, went back to flutter and it worked.
After that I ran into another issue where the alerts were not displaying in the right order so I simply changed the descending in the orderBy to true instead of false and it all worked out.

How does Firestore document snapshot work?

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.

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(),

Filtering & Sorting Firebase (Firestore) Data on a Flutter App

If my user database is on Firestore and on Registration I ask each users a set of few questions (checkboxes, radio buttons, etc). I want to create a Filter and Sort mechanism where a user is able to filter and sort a list of other users (from Firestore) based on multiple filter parameters sorted according to a particular field.
Is what I want to create even possible on Firebase (FireStore) and Flutter or do I need anything else?
Can anybody please link me to any relating Flutter/Firebase documentation, YouTube videos, or any other relevant content.
Once you fetch your list of users from Firestore, you can easily sort and filter them using the methods provided by the List class in Flutter:
sort method for sorting: https://docs.flutter.io/flutter/dart-core/List/sort.html
retainWhere method for filtering: https://docs.flutter.io/flutter/dart-core/List/retainWhere.html
You can create multiple filter and ordering in firestore in flutter app.
QuerySnapshot orderQuerySnapshot = await orderCollection
.where("status", isEqualTo: status)
.where("timestamp", isGreaterThanOrEqualTo: lowerDate)
.where("timestamp", isLessThanOrEqualTo: upperDate)
.orderBy('timestamp', descending: true)
.get();

Resources