Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multi query and pagination with firestore

I am trying to implement multi query and pagination with firestore, but once I add < or > to the query the cursor not working.

//working example:
the doc id i save as propery on the doc
ref.where('category','==' 'cats').where('status', '==', 1).orderBy('id').cursor('last doc id from the returned list').limit(3)

//not working exmple:

ref.where('category','==' 'cats').where('status', '==', 1).orderBy('price').where('price', '>=', 2).where('price', '<=', 55).orderBy('id').cursor('last doc id from the returned list').limit(3)

no error returned. is it bug with firestore or on my end.

like image 556
haim Avatar asked Oct 17 '17 05:10

haim


4 Answers

There has documentation at firebase on Pagination & Query and query data. We have to use the startAt() or startAfter() methods to define the start point for a query. Similarly, use the endAt() or endBefore() methods to define an end point for your query results.

Example: To get all cities with a population >= 1,000,000, ordered by population,

db.collection("cities")
        .orderBy("population")
        .startAt(1000000);

and to get all cities with a population <= 1,000,000, ordered by population,

db.collection("cities")
        .orderBy("population")
        .endAt(1000000);

So pagination should be done using this method like,

// Construct query for first 25 cities, ordered by population
Query first = db.collection("cities")
        .orderBy("population")
        .limit(25);

first.get()
    .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot documentSnapshots) {
            // ...

            // Get the last visible document
            DocumentSnapshot lastVisible = documentSnapshots.getDocuments()
                    .get(documentSnapshots.size() -1);

            // Construct a new query starting at this document,
            // get the next 25 cities.
            Query next = db.collection("cities")
                    .orderBy("population")
                    .startAfter(lastVisible)
                    .limit(25);

            // Use the query for pagination
            // ...
        }
    });
like image 125
Rezaul Karim Avatar answered Sep 21 '22 21:09

Rezaul Karim


A Firestore query can only have a single range condition.

From the documentation on queries:

You can combine where() filters with orderBy() and limit().

However, if you have a filter with a range comparison (<, <=, >, >=), your first ordering must be on the same field:

Invalid: Range filter and first orderBy on different fields

citiesRef.where("population", ">", 100000).orderBy("country")
like image 29
Frank van Puffelen Avatar answered Sep 20 '22 21:09

Frank van Puffelen


Check this example App using FireStore with Angular 8 app having pagination

enter image description here

using queries

limit()

orderBy()

startAt()

endBefore()

startAfter()

like image 28
Code Spy Avatar answered Sep 20 '22 21:09

Code Spy


As Frank pointed out so far firestore doesn't permit combining ranges on different properties. I hope google will fix this someday, having multiple range filters seems like a pretty essential feature for any database.

Also it's a rather ugly solution, but I guess you could leave out the .where('price', '>=', 2) part and filter out the data afterwards on the client.

like image 22
Mark Avatar answered Sep 18 '22 21:09

Mark