kosukesaigusa / geoflutterfire_plus

🌍💙🔥 geoflutterfire_plus allows your flutter apps to query geographic data saved in Cloud Firestore. This package is fork from GeoFlutterFire, and tried to be constantly maintained to work with latest Flutter SDK, Dart SDK, and other dependency packages.
https://pub.dev/packages/geoflutterfire_plus
MIT License
57 stars 7 forks source link

Query a field with the condition "isGraterThan" #229

Open HaniMontana opened 1 month ago

HaniMontana commented 1 month ago

Hello,

I am using this pluggin and my target is to get the nearby documents AND to additionally filter based on a timestamp (if the upload of the location is old I would like to ignore it).

Everything is working greate and also if I use the isEqualTo condition it can filter out the required document. Once I add a condition like isGreaterThan it is first of all throwing an error: package:cloud_firestore/src/query.dart': Failed assertion: line 492 pos 13: 'conditionField == orders[0][0]': The initial orderBy() field "[[FieldPath([position, geohash]), false]][0][0]" has to be the same as the where() field parameter "FieldPath([lastpositionupdate])" when an inequality operator is invoked

After that I just added .orderBy and the error is gone, but I am not able to find any document. Is this the orderBy limitation of the Plugin or did I miss something.

Thank you!

kosukesaigusa commented 1 month ago

Thank you for your message @HaniMontana !

Let me check the issue!

If possible, could you share the minimal reproducible code sample?

Thank you,

kosukesaigusa commented 1 month ago

@HaniMontana

As you see the following part:

https://github.com/KosukeSaigusa/geoflutterfire_plus/blob/447e6b9f620eb6fb10c3e2734824c1788e3e06c6/lib/src/geo_collection_reference.dart#L332-L346

I think the query executed in the end is going to like this:

FirebaseFirestore.instance.collection('locations')
    .where('lastUpdateTimestamp', isGreaterThan: someTimestamp)
    .orderBy('lastUpdateTimestamp')
    .orderBy('position.geohash')
    .startAt(['someStartGeohash'])
    .endAt(['someEndGeohash'])

It requires composite index, but do you create the index, probably clicking the console error URL link or from the Cloud Firestore console?

HaniMontana commented 1 month ago

Hi @kosukesaigusa Thanks for your support.

In the following you can finde the code snippet. I hope it helps.


final typedCollectionReference =
    FirebaseFirestore.instance.collection('User').withConverter<UserCol>(
          fromFirestore: (ds, _) => UserCol.fromDocumentSnapshot(ds),
          toFirestore: (obj, _) => obj.toJson(),
        );

    Query<UserCol> queryBuilder(Query<UserCol> query) =>
    query.where("lastpositionupdate", isGreaterThanOrEqualTo:  Utils.fromDateTimeToJson(referenceDate)).orderBy('lastpositionupdate').orderBy('position.geohash'); 

  final Stream<List<DocumentSnapshot<UserCol>>> stream =
        plus.GeoCollectionReference<UserCol>(typedCollectionReference)
            .subscribeWithin(center: visibleLocation, radiusInKm: filter.radius, field: 'position', geopointFrom: (UserCol user) => user.geopoint,
      // Specify queryBuilder parameter here.
      queryBuilder: queryBuilder,
      strictMode: true,
    );
    await for (final documentList in stream) {
      for (var i = 0; i < documentList.length; i++) {
          userCol = documentList[i].data() as UserCol;     

I tried with both orderby, but it thows an error: [cloud_firestore/invalid-argument] Client specified an invalid argument. Note that this differs from failed-precondition. invalid-argument indicates arguments that are problematic regardless of the state of the system (e.g., an invalid field name).

When I only use on orderby, there is no error, but there is no data. When I change from isGreater than to isEqualTo and remove the orderby everythign works well.

And the point with .startAt(['someStartGeohash']).endAt(['someEndGeohash']) I didnt get how to use it...