GeoFlutterFire icon indicating copy to clipboard operation
GeoFlutterFire copied to clipboard

Is it possible to use as one query instead of stream?

Open felpsio opened this issue 5 years ago • 22 comments

I need to use the geolocation query just once in a while instead of keeping a stream open. Is there a way to do it in the current implementation?

If anyone had an idea how to implement this in the plugin I can help with the implementation/PR

felpsio avatar Apr 11 '19 04:04 felpsio

This is the actual query, and its a run on 9 geo-hashes - 1 center, and 8 surroundings which is then used to create streams as shown here. So, there's no single query that can be exposed! The streams from all 9 queries are merged and a further filtered on distance. Hope this helps

DarshanGowda0 avatar Apr 18 '19 13:04 DarshanGowda0

Thank you @DarshanGowda0. I need to query just once in a while for a limited number of results. I'm developing a newsfeed of posts that has a distance filter. So soon I gonna try to get the results just once instead of keep listening all the time for the answers.

Your reply gave me some ideas on how to do it :).

felpsio avatar Apr 18 '19 14:04 felpsio

Happy to help 😄 I guess we'll need a getDocuments() with Futures implementation as well, along with streams? replacing ref.snapShots() with ref.getDocuments() here should help you get futures instead of streams. I'll try to write another within function for just this.

DarshanGowda0 avatar Apr 18 '19 14:04 DarshanGowda0

Yes. Have something like getDocuments() would be very helpful. I'm finishing other features, and then I'll come back to this need :)

felpsio avatar Apr 18 '19 14:04 felpsio

@felipecesar42 Did you manage to get only 1 result to pop up? I also don't want it to listen all the time.

mike-gallego avatar May 02 '19 14:05 mike-gallego

Not yet. I'm finishing other things before being able to focus on this feature. But if you decide to start I can try to help :)

felpsio avatar May 02 '19 17:05 felpsio

This is the actual query, and its a run on 9 geo-hashes - 1 center, and 8 surroundings which is then used to create streams as shown here. So, there's no single query that can be exposed! The streams from all 9 queries are merged and a further filtered on distance. Hope this helps

I was wondering when looking at the method if that actually still works if you get near the poles of the earth - a location where the tiles tend to get very small? I would think that int precision = Util.setPrecision(radius); in collection.dart should not only take the radius into account but also the location of the query.

Haves1001 avatar May 04 '19 11:05 Haves1001

I had a query like this:

    return Firestore.instance
        .collection('places')
        .getDocuments()
        .then((data) => data.documents
            .map((doc) => Place(
                  id: doc["id"],
                  title: doc["title"],
                ))
            .toList());

I changed it to use within like:

    return _geo
        .collection(collectionRef: Firestore.instance.collection('places'))
        .within(
            center: center,
            radius: 100,
            field: 'geoLocation',
            strictMode: true)
        .first
        .then((documents) => documents
            .map((doc) => Place(
                id: doc["id"],
                title: doc["title"],
                ))
            .toList());

Note that I used first to transform the Stream into a Future.

awhitford avatar May 05 '19 00:05 awhitford

I am having a similar issue, however the reasoning to have a one time shot query is that the underlying stream is not canceled, when using @awhitford way of converting it into a future The collection I query is protected by security rules, which leads then to exceptions on the stream, when signing out:

W/Firestore(15056): (19.0.0) [Firestore]: Listen for Query(rides order by start_location.location.geohash, name) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null} I/System.out(15056): com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.

I suspect the issue is the returned broadcaststream.

Maybe I oversee something, looking forward for feedback

gnalFF avatar May 21 '19 20:05 gnalFF

Hi,

I just came back to this feature. Looks like it's impossible to convert to a Query. The best thing we can do is limit it artificially: create some kind of listener that keeps counting the number of documents retrieved and after reaching the threshold it cancels the subscription.

I searched for other implementations of this kind of query in other platforms. Looks like even in the web platforms (that have much more users than Flutter) they couldn't find a way to get this just a Query instead of Streams. Hopefully someday Firebase will improve their queries features, it's very limited so far and there's not a simple way to do complex queries even if the query isn't related to geolocation.

If someone finds another library in other platforms that solved this problem I would be happy to look their code and bring to this package.

@DarshanGowda0 do you know if I cancel the stream received from the within function if it will cancel all the substreams associated with it?

felpsio avatar May 30 '19 05:05 felpsio

Any news on this? This feature is missing!

klaszlo8207 avatar Aug 29 '19 07:08 klaszlo8207

Agreed, this would be very useful

tzvc avatar Nov 02 '19 17:11 tzvc

This seems work.

    List<Place> ret = [];
    await geo
        .collection(collectionRef: queryRef)
        .within(center: center, radius: radius, field: 'location')
        .first
        .then((docs) {
      Future.forEach(docs, (DocumentSnapshot doc) {
        // parse place
       ret.add(place)
      }).whenComplete(() {
        return;
      });
    });
    return ret;

I'm not sure about the race condition this may cause. e.g. not all 9 queries available for the first steam. It would be nice if someone can confirm this.

MartinJLee avatar May 23 '20 09:05 MartinJLee

@MartinJLee , how would you get distance like this?

lizbrownwood avatar Jun 04 '20 19:06 lizbrownwood

@MartinJLee , how would you get distance like this?

I'm not sure what distance you are after. Share your query code here so others can help you.

MartinJLee avatar Jun 04 '20 23:06 MartinJLee

@lizbrownwood Do you mean something like this #87 ? There is a pull request to, which has to be accepted ( #88 ).

webertim avatar Jun 05 '20 08:06 webertim

any update on that? I need a Future too. Listening all the time will lead to unnecessary bills from Firestore.

rinati avatar Aug 01 '20 09:08 rinati

same here, would like to avoid unnecessary bills from Firestore for listening continuously

yulkin2002 avatar Nov 18 '20 15:11 yulkin2002

The same problem continues..

akcadev avatar Dec 06 '20 23:12 akcadev

bump

Beautylivery avatar Mar 02 '21 23:03 Beautylivery

Hey guys, sorry for such a delay. The author is very busy, from now on we help him to maintain the package.

@webertim I'll check your pull request. I think there will be some fixes because of such a delay with merging. Would you like to fix them or should we do it?

Just for your info - now we have two working branches - master and 3x_null_safety.

awaik avatar Mar 07 '21 18:03 awaik

How about using a StreamController like so https://stackoverflow.com/questions/60663818/flutter-how-to-refresh-streambuilder

giorgio79 avatar Feb 26 '23 18:02 giorgio79