fluttercommunity / firestore_helpers

Firestore Helpers - Firestore helper function to create dynamic and location based queries. Maintainer: @escamoteur
https://pub.dev/packages/firestore_helpers
MIT License
48 stars 19 forks source link

I have a code like given below how can I use this I want display list by distance from user #2

Closed hitanshu1 closed 6 years ago

hitanshu1 commented 6 years ago

[List _offers = [];

List get offers => _offers;

BuildContext buildContext;

class OffersGrid extends StatelessWidget { OffersGrid({@required BuildContext context}) { buildContext = context; }

@override Widget build(BuildContext context) { CollectionReference offerReference = Firestore.instance.collection(OFFER_COLLECTION); Query filterQuery;

if (startPrice != 0) {
  if (filterQuery == null) {
    filterQuery = offerReference.where(OFFER_PRICE, isGreaterThanOrEqualTo: startPrice);
  } else {
    filterQuery = filterQuery.where(OFFER_PRICE, isGreaterThanOrEqualTo: startPrice);
  }
}
if (endPrice != 0) {
  if (filterQuery == null) {
    filterQuery = offerReference.where(OFFER_PRICE, isLessThanOrEqualTo: endPrice);

  } else {
    filterQuery = filterQuery.where(OFFER_PRICE, isLessThanOrEqualTo: endPrice);

  }
}

if (selectedOfferCategory != null) {
  if (filterQuery == null)
    filterQuery = offerReference.where(OFFEER_CATEGORY, isEqualTo: selectedOfferCategory.text);
  else
    filterQuery = filterQuery.where(OFFEER_CATEGORY, isEqualTo: selectedOfferCategory.text);

}

return new StreamBuilder<QuerySnapshot>(
  stream: filterQuery != null ? filterQuery.snapshots() : offerReference.snapshots(),
  builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
    if (!snapshot.hasData) return new Center(child: new CircularProgressIndicator());
    if (snapshot.data.documents.length == 0) return new Center(child: new Text('No data available', style: new TextStyle(fontSize: 20.0,fontFamily: "SnackerComic",color: Colors.black),),);
    return new StaggeredGridView.count(
      physics: new BouncingScrollPhysics(),
      crossAxisCount: MediaQuery.of(context).orientation == Orientation.portrait ? 2 : 3,
      children: buildGrid(snapshot.data.documents),
      staggeredTiles: generateRandomTiles(snapshot.data.documents.length),
    );
  },
);

} }

List buildGrid(List documents) { List _gridItems = []; _offers.clear();

for (DocumentSnapshot document in documents) { _offers.add(Offer.fromDocument(document)); }

for (Offer offer in _offers) { _gridItems.add(buildGridItem(offer)); }

return _gridItems; } ](url)

escamoteur commented 6 years ago

Could you please descibe what your problem is before I delve into your code? Thanks

hitanshu1 commented 6 years ago

actually I m try to query with near by location from user ...but don't understand how use ur package ..

escamoteur commented 6 years ago

Did you read the docs on getDataInArea? What exactly do you not understand?

hitanshu1 commented 6 years ago

yes but If give me a example source if you can then it is very helpful for me to understand

escamoteur commented 6 years ago

I found a little bug in the example code perhaps that confused you. I did not pass a CollectionReference

// We will define a wrapper class because we want our Event plut its distance back

class EventData{
  Event event;
  double distance;

  EventData(this.event, [this.distance]) 
}

Stream<List<EventData>> getEvents(area) {
  try {
    return getDataInArea(
        collection: Firestore.instance.collection("events"),
        area: area,
        locationFieldNameInDB: 'loction',        
        mapper: (eventDoc) {
          var event = _eventSerializer.fromMap(eventDoc.data);
          // if you serializer does not pass types like GeoPoint through
          // you have to add that fields manually. If using `jaguar_serializer` 
          // add @pass attribute to the GeoPoint field and you can omit this. 
          event.location = eventDoc.data['location'] as GeoPoint;
          event.id = eventDoc.documentID;
          return new EventData(event);
        },
        locationAccessor: (eventData) => eventData.event.location,
        distanceMapper: (eventData, distance) {
          eventData.distance = distance;
          return eventData;
        },
        distanceAccessor: (eventData) => eventDatas.distance, 
        clientSitefilters: (event) => event.startTime > DateTime.now()  // filer only future events
      );
  } on Exception catch (ex) {
    print(ex);
  }
  return null;
}
hitanshu1 commented 6 years ago

sorry and Thanks .. let me try again

AhabLives commented 6 years ago

How do you correctly pass Area agrument ? I get the following error with the code below. Thanks.

I/flutter (15168): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═════════════════════════════════════════════════ I/flutter (15168): The following assertion was thrown while handling a gesture: I/flutter (15168): type 'Area' is not a subtype of type 'Area' where I/flutter (15168): Area is from package:callsheet/TestGeoHelpers.dart I/flutter (15168): Area is from package:firestore_helpers/src/geo_helpers.dart

class TestGeoHelpers extends StatefulWidget {
  @override
  _TestGeoHelpersState createState() => new _TestGeoHelpersState();
}

class _TestGeoHelpersState extends State<TestGeoHelpers> {

  double _lat = 34.0522342;
  double _lng = -118.24368489999999;

  String _geoResultsString='...';

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(title: new Text('TestGeoHelpers'),),
        body: new Container(alignment: Alignment.center, padding: EdgeInsets.all(16.0),
            child: new Column(
                children: <Widget>[
                new RaisedButton(
                    child: new Text('Get Geo Data'),
                    onPressed: (){

                      print('MapFilerSettings.....slected.... check _lat = ' + _lat.toString());
                      print('MapFilerSettings.....slected.... check _lng = ' + _lng.toString());
                      GeoPoint areaGP = new GeoPoint(_lat, _lng);
                      Area searchArea = new Area(areaGP, 50.0);

                      getEvents(searchArea);
                    },
                ),
                  new Text(_geoResultsString),
                ],
            ),
        ),
    );
  }

  Stream<List<EventData>> getEvents(area) {
    print('MapFilerSettings..................getEvents...hit.... check  Area = ' + area.center.latitude.toString());

    try {
      return getDataInArea(
          collection: Firestore.instance.collection('users'),
          area: area,
          locationFieldNameInDB: 'geoPoint',
          mapper: (eventDoc) {

            print('mapFilterSettings.....getGeoPointsByRadius....data: '+eventDoc.data['email'].toString());
            setState(() {

              _geoResultsString = eventDoc.data['email'].toString();

            });
          },
          );
    } on Exception catch (ex) {
      print(ex);
    }
    return null;
  }

}

class Event{
  String id;
  String name;
  DateTime startTime;
  GeoPoint location;
}

class EventData{
  Event event;
  double distance;

  EventData(this.event, [this.distance]);
}

class Area {
  final GeoPoint center;
  final double radiusInKilometers;

  Area(this.center, this.radiusInKilometers):
  assert(geoPointValid(center)), assert(radiusInKilometers >= 0);

  factory Area.inMeters(GeoPoint gp, int radiusInMeters) {
    return new Area(gp, radiusInMeters / 1000.0);
  }

  factory Area.inMiles(GeoPoint gp, int radiusMiles) {
    return new Area(gp, radiusMiles * 1.60934);
  }

  /// returns the distance in km of [point] to center
  double distanceToCenter(GeoPoint point) {
    return distanceInKilometers(center, point);
  }
}
escamoteur commented 6 years ago

@ZackMekonen you are mixing too types of Area from too packages as the error tells you. Make sure you use the one from firestore_helpers

AhabLives commented 6 years ago

@escamoteur Thanks for the help. I have removed the Area Class and the type mismatch conflict/error is no longer an issue. However the method now simply returns nothing. Could this be a result of Firestore.instance.collection... not connecting/hanging ?

the last line of logs with no errors shows I/flutter (15168): MapFilerSettings.........getEvents...begin.... check Area = 34.0522342

//the new method
  Stream<List<EventData>> getEvents(area) {

    GeoPoint areaGP = new GeoPoint(_lat, _lng);
    Area searchArea = new Area(areaGP, 50.0);
    print('MapFilerSettings.........getEvents...begin.... check  Area = ' + searchArea.center.latitude.toString());
    try {
      return getDataInArea(
          collection: Firestore.instance.collection('users'),
          area: searchArea,
          locationFieldNameInDB: 'geoPoint',
          mapper: (eventDoc) {
            print('mapFiterSettings.....getGeoPointsByRadius....mapper: evetnDoc...');
            print('mapFiterSettings.....getGeoPointsByRadius....data: '+eventDoc.data['email'].toString());
          },

      );
    } on Exception catch (ex) {
      print(ex);
      print('mapFiterSettings.....getGeoPointsByRadius..error...'+ex.toString());
    }
    print('mapFiterSettings.....getGeoPointsByRadius..end...');
    return null;
  }
`
escamoteur commented 6 years ago

Check if you miss an index in FireStore. Heck the debug output it tells you what to do in this case

AhabLives commented 6 years ago

@escamoteur For the record my debug output make no mention of idexing a field (only my print statements all the way down). I will try indexing geoPoint field with emial field.

escamoteur commented 6 years ago

Did you solve your problem?

AhabLives commented 6 years ago

Unfortunately no. Thanks for the help any way. I tried indexing in many variations to no success. I finally used platform channels to achieve the desired result.

escamoteur commented 6 years ago

But why over platform channels? Just without firestore_helpers only with the cloud_firestore package didn't work?