skip to Main Content

I have the following code to query properties (paginated) with filters:

const propertyCollectionRef = db.collection('properties')

    let queryRef = propertyCollectionRef;

    let query: any = db.collection('properties');

    if (filters) {
        for (const [key, value] of Object.entries(filters)) {
            if (key !== 'page') {
                switch (key) {
                    case "price":
                        query = query.where(key, '<=', parseInt(value));
                        break;
                    case "bathrooms":
                        query = query.where(key, '==', parseInt(value));
                        break;
                    case "beds":
                        query = query.where(key, '==', parseInt(value));
                        break;
                    case "min-area":
                        query = query.where("area", '>=', parseInt(value));
                        break;
                    case "max-area":
                        query = query.where("area", '<=', parseInt(value));
                        break;
                    case "typ":
                        query = query.where(key, '==', value);
                        break;
                    default:
                        query = query.where(key, '==', value);
                        break;
                }
            }
        }
    }



    const offset = (page - 1) * pageSize

    const querySnapshot = await query
        .limit(pageSize)
        .offset(offset).get();

firebase wants me to create an index for each query combination (

code: 9,
  details: 'The query requires an index. You can create it here:...

) made when choosing different filters, for example, I need to create one for filtering price and type. but also one when filtering for price, type, and bathrooms

how is it possible to make this more "generic" – I can’t think of firebase to make it such complicated…

2

Answers


  1. Chosen as BEST ANSWER

    i will answer the question by my own and maybe for somebody who is also stepping across this situation:

    in general its not possible to filter a collection as i did as in a in a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field - in my case i needed it for four range filter fields.

    after checking the docs and some other repos i saw that in my situation it is the best to use only one range filter for the geoposition, to make this happen i use GeoFire which uses geohashes so only one field is required for the range filter. Please check out this video it is explained brilliant how to query for geopoints in firebase

    let query: any = propertyCollectionRef.near({ center: new firestore.GeoPoint(lat, lng
            ), radius: radius });
    

    i use then one more "equal" filter to decrease the loaded data with the rent type (for rent, for sale) ...

    the rest of the range filters price, bathrooms, beds, ... are applied client side with a simpel if/else

    it's the best way i've found so far to handle my query


  2. Firebase wants me to create an index for each query combination.

    Cloud Firestore guarantees the query performance by requiring an index for every query. The indexes required for the most basic queries are automatically created for you. There is nothing that you should do. However, for more complex queries like yours, an index is required. One thing to notice is that you can create up to 200 indexes. If you need more than 200, then you can contact Firebase Support to request an increase to this limit.

    Besides that, the indexes are created automatically. So that being said, queries like yours cannot work without creating indexes.

    The indexes are created automatically but still require me to click on the link.

    Yes, that’s correct. If you don’t want to do that yourself by clicking the URLs or by creating the indexes directly in the Firebase Console, then you should consider using the Firebase CLI. This allows you to deploy indexes with the Firebase CLI very easily.

    Is it really so that most queries only use one range filter and do the rest client side?

    For such queries, yes, here is a list of all query limitations in Firestore.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search