protectedWithinWithDistance method

  1. @protected
Stream<List<DistanceDocSnapshot<Map<String, dynamic>>>> protectedWithinWithDistance({
  1. required GeoFirePoint center,
  2. required double radius,
  3. required String field,
  4. required int limit,
  5. required GeoPoint? geopointFrom(
    1. Map<String, dynamic> t
    ),
  6. required bool? strictMode,
})
inherited

query firestore documents based on geographic radius from geoFirePoint center field specifies the name of the key in the document

Implementation

@protected
Stream<List<DistanceDocSnapshot<T>>> protectedWithinWithDistance({
  required GeoFirePoint center,
  required double radius,
  required String field,
  required int limit, // Added By Uraam
  required GeoPoint? Function(T t) geopointFrom,
  required bool? strictMode,
}) {
  final nonNullStrictMode = strictMode ?? false;

  final precision = MathUtils.setPrecision(radius);
  final centerHash = center.hash.substring(0, precision);
  final area = GeoFirePoint.neighborsOf(hash: centerHash)..add(centerHash);

  final queries = area.map((hash) {
    final tempQuery = _queryPoint(hash, field);
    return _createStream(tempQuery).map((querySnapshot) {
      return querySnapshot.docs;
    });
  });

  final mergedObservable = mergeObservable(queries);

  final filtered = mergedObservable.map((list) {
    final mappedList = list.map((documentSnapshot) {
      final snapData =
          documentSnapshot.exists ? documentSnapshot.data() : null;

      assert(snapData != null, 'Data in one of the docs is empty');
      if (snapData == null) return null;
      // We will handle it to fail gracefully

      final geoPoint = geopointFrom(snapData);
      assert(geoPoint != null, 'Couldnt find geopoint from stored data');
      if (geoPoint == null) return null;
      // We will handle it to fail gracefully

      final kmDistance = center.kmDistance(
        lat: geoPoint.latitude,
        lng: geoPoint.longitude,
      );
      return DistanceDocSnapshot(
        documentSnapshot: documentSnapshot,
        kmDistance: kmDistance,
      );
    });

    final nullableFilteredList = nonNullStrictMode
        ? mappedList
            .where((doc) =>
                    doc != null &&
                    doc.kmDistance <=
                        radius * 1.02 // buffer for edge distances;
                )
            .toList()
        : mappedList.toList();
    final filteredList = nullableFilteredList.whereNotNull().toList();

    filteredList.sort(
      (a, b) => (a.kmDistance * 1000).toInt() - (b.kmDistance * 1000).toInt(),
    );
    return filteredList;
  });
  return filtered.asBroadcastStream();
}