Search code examples
flutterdartgoogle-cloud-firestorerangeslider

Unable to get document on using where in in flutter firebase (cloud firestore)


I am trying to filter my products based on the price range set by the user. For this am using range slider but am not getting any product in this range:- Code for range slider:-

SfRangeSlider(
            min: 0.0,
            max: 20000.0,
            showLabels: true,
            showTicks: true,
            enableTooltip: true,
            values: _values,
            activeColor: Themes.selectedColor,
            inactiveColor: const Color(0xffc0c0c0),
            tooltipTextFormatterCallback: (a, s)=>"₹ $s",
            onChanged: (SfRangeValues newValues) {
              products.removeWhere((element) => element.price!<_values.start&&element.price!>_values.end);
              if(products.length<8){
                getData();
              }
              setState(() {
                _values = newValues;
              });
            },
          ),

and my code to fetch the data:-

void getData()async
  {
    QuerySnapshot snapshot=await productReference.where('category',isEqualTo: widget.category).where("price",whereIn: [_values.start,_values.end]).limit(12).get();
    if(snapshot.docs.isNotEmpty){
      for (DocumentSnapshot doc in snapshot.docs) {
        products.add(ProductModel.fromDocument(doc));
      }
      lastDoc=snapshot.docs.last;
    }
    setState(() {
      loading=false;
      load=false;
    });
  }

But i am not able to receive any document. Even though product exists in the price range. For testing i choose 0 and 20,000 as default value to check.

P.S:- Do i need to create any index? If so then what values for it?


Solution

  • whereIn checks for exact match with the values you give.

    What you want to do is:

    QuerySnapshot snapshot = await productReference
        .where('price', isLessThanOrEqualTo: _values.end)
        .where('price', isGreaterThanOrEqualTo: _values.start)
        .limit(12)
        .get();
    

    For your question regarding indexes: If you need to create one, firestore will likely tell you and give you a ling to create it automatically so I would not worry about that.

    Another note: I think your method of retrieving data will cause a lot of calls to the database. Maybe a better solution would be to only fetch data when the user stops updating the slider values. Here is how to achieve that:

    Listener(
      behavior: HitTestBehavior.translucent,
      onPointerUp: (_) {
        // Listen to pointer up and ONLY retrieve data when this happens
        products.removeWhere((element) =>
        element.price! < _values.start && element.price! > _values.end);
        if (products.length < 8) {
          getData();
        }
      },
      child: SfRangeSlider(
        min: 0.0,
        max: 20000.0,
        showLabels: true,
        showTicks: true,
        enableTooltip: true,
        values: _values,
        inactiveColor: const Color(0xffc0c0c0),
        tooltipTextFormatterCallback: (a, s) => "₹ $s",
        onChanged: (SfRangeValues newValues) {
          // DON'T fetch the state here, only update the values
          setState(() {
            _values = newValues;
          });
        },
      ),
    )