OrderBy not working
hasseye opened this issue · 8 comments
Really cool what you're doing with this package. Unfortunately for Flutter, this is such a fragmented space and no packages appear to have got it right so far for Firestore GeoPoint Queries.
My big issue is being able to use the "OrderBy" feature. I switched to your package because you had a QueryBuilder, but once I try to do an OrderBy there, it hangs up again and nothing shows.
@hasseye
Thank you for using our package and creating an issue!
May I ask you to share your codes using orderBy
in queryBuilder
parameter? And if you find any error messages in your debug console, I also would like you to share the message or screenshot.
I would like to check and reproduce it, and try to solve the problem!
@kosukesaigusa Thanks for the fast response. Here's my code:
final CollectionReference<Map<String, dynamic>> collectionReference = firestore.collection('posts');
GeoFirePoint center = GeoFirePoint(GeoPoint(lat, lon));
final Stream<List<DocumentSnapshot<Map<String, dynamic>>>> stream =
GeoCollectionReference<Map<String, dynamic>>(collectionReference)
.subscribeWithin(
center: center,
radiusInKm: 200,
field: 'location',
queryBuilder: (Query<Map<String, dynamic>>? collection) => collection?.orderBy('createdAt', descending: false),
geopointFrom: (data) => data['location']['geopoint'] as GeoPoint);
The queryBuilder is what's causing the issue. In the original GeoFlutterFire I guess orderBy didn't work because the way it was calling the geopoint query. Wasn't sure if you happened to find another way to resolve it. Per the official documentation "limit() and orderBy() are not supported at the moment. limit() could be used to limit docs inside each hash individually which would result in running limit on all 9 hashes inside the specified radius. orderBy() is first run on geohashes in the library, hence appending orderBy() with another field wouldn't produce expected results. Alternatively documents can be sorted on client side."
@hasseye
Thank you for your additional information!
I think currently orderBy
is not available in our geoflutterfire_plus package for the same reason as original GeoFlutterFire...!
Because 9 different snapshots by 9 neighbor geohashes are merged on client side, so even if you can order them by orderBy
for each snapshot, once they are merged, its order will be in correct as a whole result. I think it's better to sort them on client side after getting the query result.
But let me take time and think of the solution, if I find anything, I will let you know and implement it!
@kosukesaigusa I appreciate it. I believe the JS package recommended by the Flutter/Firebase team DO have ordering and limit that works, so not entirely sure how they do it, but may be something to look into. Happy to help too.
Hey @kosukesaigusa
I am currently facing a similar issue relating to the querybuilder parameter.
My Event Document has the relevant location field with geohash and geopoint data inside it.
The Document also has a Timestamp field called 'date'.
When I am using querybuilder to filter out past events, I get no documents back.
I set up an index in Firestore and I get no errors when running the queries but I have a feeling that the issue might be the inequality operator on the date field. Using 'isEqualTo' on a different field works for me.
Do You know if inequality operators work? And if not, I'd be happy to help out making them work.
GeoCollectionReference(EventDocService().eventsCollection)
.subscribeWithin(
center: GeoFirePoint(centerGeoPoint),
radiusInKm: radiusInKm,
field: 'location',
geopointFrom: (data) => data.location.geoPoint,
strictMode: true,
queryBuilder: (query) => query
.orderBy('date')
.where('date', isGreaterThanOrEqualTo: DateTime.now()),
)
.listen(_updateMarkers);
@domidanke
Thank you for your message and using geoflutter_plus package!
I set up an index in Firestore and I get no errors when running the queries but I have a feeling that the issue might be the inequality operator on the date field. Using 'isEqualTo' on a different field works for me.
Could you share the source codes which work without problems (and possibly screenshots of Cloud Firestore console of the collection/documents)?
I think, currently if you give queries which includes orderBy
to queryBuilder
, it will fail because of Cloud Firestore query restriction. Also, I confirmed that the same thing is reproduced when using GeoFlutterFire2 as well and we can find an explanation about the limitations here: https://github.com/beerstorm-net/geoflutterfire2#limitations.
I will try to come up with its solutions, but first, will write the similar explanation in geoflutterfire_plus README, and of course, if you find any ways to solve it, your future comments or PRs are always welcome🙌
Thank you for the quick response @kosukesaigusa.
Firestore's restrictions really make this quite impossible for me right now. The link you sent confirms my issue.
I will come back to this in the future :)
but even if orderBy or limit is not supported by Firebase for Geo Queries, the queryBuilder does not run if there is not orderBy (as one does a querybuilder without the orderBy, an error is thrown, meaning the queryBuilder parameter is redudant and not usable. Any of the codes below wont work:
queryBuilder: (query) {
return query.where(Str.UID,
isNotEqualTo: FirebaseAuth.instance.currentUser!.uid);
// .orderBy(Str.UID)
// .orderBy(field);
},
queryBuilder: (query) {
return query.where(Str.UID,
isNotEqualTo: FirebaseAuth.instance.currentUser!.uid);
.orderBy(Str.UID)
.orderBy(field);
},
in simple terms, the query builder expects a query in reference to the CollectionReference, on the other hand, Firebase expects the query to have an OrderBy, yet the OrderBy is not supported with GeoQueries. Even with just a Query without OrderBy should be supported as a parameter taken in by the GeoFlutterFire plus to emit a stream based on filtered documents.