geoflutterfire stream to Future - flutter

I have to query the geoflutterfire data with a Stream.
But I would like to use this in a Future in a ChangeNotifierprovider to be able to wait until the Stream has all data.
I never built a Future with a Stream in it before. What do I have to return?
When I don't have a return and just do notifyListeners(), the function runs forever. So I just put in return true.
Is there a better way to do this?
Future<void> fetchPlacesNearBy(double lat, double lng) async {
print("GETTING FIRESTORE PLACES");
GeoFirePoint center = geo.point(latitude: lat, longitude: lng);
double radius = 5; //in km
String field = 'geo_location';
// Reading nearby places based on lat, lng parameters
try {
Stream<List<DocumentSnapshot>> placesStream =
geo.collection(collectionRef: _placesRef).within(
center: center,
radius: radius,
field: field,
strictMode: false,
); // = false includes borderline places
await for (var doclist in placesStream) {
topWikiPlacesAroundUser2 = [];
if (doclist.length > 0) {
for (DocumentSnapshot ds in doclist) {
/// Init place model
WunderkPlace pl = WunderkPlace.fromMap(
ds.data(), ds.get('geo_location.geopoint'));
topWikiPlacesAroundUser2.add(pl);
}
} else {
print('Nearby places do not exist in the database');
}
notifyListeners();
return true;
}
} catch (e) {
print(e);
return false;
}
}

Related

Complex Firebase query with geofire

Query<Map<String, dynamic>> collectionReference
Type: Query<Map<String, dynamic>>
The argument type 'Query<Map<String, dynamic>>' can't be assigned to the parameter type 'CollectionReference<Object?>'.
We are trying to query our task collection and filter it based on topic, status, userid but we are getting the above error.
We are using the Geofire lib along with Firebase
Future<void> fetchTasksNearBy(double lat, double lng) async {
print('getting tasks in location');
GeoFirePoint center = geo.point(latitude: lat, longitude: lng);
double radius = 60; //in km
String field = 'location';
// Reading nearby tasks based on lat, lng parameters
try {
var collectionReference = tasksRef
.where('status', isEqualTo: 'Posted')
.where('ownerId', isNotEqualTo: widget.user!.id)
.where('category.subCategoryId', isEqualTo: widget.subCat);
Stream<List<DocumentSnapshot>> placesStream =
geo.collection(collectionRef: collectionReference).within(
center: center,
radius: radius,
field: field,
strictMode: true,
); // = false includes borderline places
await for (var doclist in placesStream) {
if (doclist.isNotEmpty) {
for (DocumentSnapshot ds in doclist) {
print('${ds.id} ${ds['title']}');
}
} else {
print('Nearby tasks do not exist in the database');
}
}
} catch (e) {
print(e);
}
}

Geoflutterfire with where condition `isGreaterThan` not working

I am trying to query time with condition isGreaterThan, but it doesn't show data.
The code is correct, but I don't know problem.
I want to show data time isGreater selected time.
I think to there is problem in Geoflutterfire with condition isGreaterThan.
_setStream() async {
_locationData = await location.getLocation();
var pos = await location.getLocation();
double lat = pos.latitude!;
double lng = pos.longitude!;
print('timeeeeeeeee$_time');
int _ti = Timestamp.now().millisecondsSinceEpoch - 999 * 60 * widget.time;
var ref = await FirebaseFirestore.instance
.collection('now')
.where('gender', isEqualTo: widget.gender)
.where('time', isGreaterThan: _ti)
.orderBy('time', descending: true);
GeoFirePoint center = geo.point(latitude: lat, longitude: lng);
stream = radius.switchMap((rad) {
var collectionReference = ref;
return geo.collection(collectionRef: collectionReference).within(
center: center, radius: rad, field: 'location', strictMode: true);
});
setState(() {
isLoading = false;
});
stream = geo.collection(collectionRef: ref).within(
center: center,
radius: widget.distance,
field: 'location',
strictMode: true);
stream!.listen((List<DocumentSnapshot> documentList) {
documentList.forEach((element) {
print("from data .......element");
print(element.data());
final data = element.data() as Map<String, dynamic>;
final GeoPoint point = data['location']['geopoint'];
print("from data .......latitude");
print(point.latitude);
});
});
}
Firestore queries can only perform range conditions (>= and such) on a single field. When you use GeoFire, it already needs to perform this condition on the geohash value to perform the geoquery, so you can't perform a range condition on any other field.
If you want to understand why that is, I recommend watching this video on implementing geoqueries on Firebase's NoSQL databases.
If also recommend checking this answer I gave recently on adding an additional range filter to a geoquery, which covers common workarounds: Is it possible to query Firebase Firestore by both a location and age range?

Query with condition isNotEqualTo not work in flutter

I have a problem with the query with the condition isNotEqualTo does not work and does not show the values ​​checked from the condition, note that I tried the condition isNotEqualTo and it worked
What is the problem
_setStream() async {
var pos = await location.getLocation();
double lat = pos.latitude!;
double lng = pos.longitude!;
var ref = await FirebaseFirestore.instance.collection('now')
.where('uid', isNotEqualTo: _user.uid).orderBy('uid');
GeoFirePoint center = geo.point(latitude: lat, longitude: lng);
stream = radius.switchMap((rad) {
var collectionReference = ref;
return geo.collection(collectionRef: collectionReference).within(
center: center, radius: rad, field: 'location', strictMode: true);
});
setState(() {
isLoading = false;
});
stream = geo.collection(collectionRef: ref).within(
center: center, radius: 2000, field: 'location', strictMode: true);
stream!.listen((List<DocumentSnapshot> documentList) {
documentList.forEach((element) {
print("from data .......element");
print(element.data());
final data = element.data() as Map<String, dynamic>;
final GeoPoint point = data['location']['geopoint'];
print("from data .......latitude");
print(point.latitude);
});
});
}
Even though NotEqual query is available in firebase, it was made available late in flutter plugin. The best option is to fetch all to a list and remove unwanted elements from the list

I can't get result of Future

I have this initState:
#override
void initState() {
super.initState();
_initState();
}
_initState() async {
_geIdsList().then((result) {
_idList = result;
print('result $_idList');
}, onError: (e) {
print('error $e');
});
}
Then there's my function to fetch the IDs from Firestore:
Future<List<String>> _geIdsList() async {
List<String> ids = [];
StreamSubscription stream;
Firestore _firestore = Firestore.instance;
Geoflutterfire geo;
var collectionReference = _firestore.collection('locations');
geo = Geoflutterfire();
var location = new Location();
var pos = await location.getLocation();
var radius = BehaviorSubject<double>.seeded(10.0);
GeoFirePoint center = geo.point(latitude: pos.latitude.toDouble(), longitude: pos.longitude.toDouble());
stream = radius.switchMap((rad) {
return geo.collection(collectionRef: collectionReference).within(
center: center, radius: rad, field: 'position', strictMode: true);
}).listen((List<DocumentSnapshot> documentList) {
Future.forEach(documentList, (DocumentSnapshot documentSnapshot) {
print('document here ... $documentSnapshot' );
print(documentSnapshot.data['id']);
var id = documentSnapshot.data['id'].toString();
ids.add(id);
}).whenComplete(() {
stream.cancel();
print('ids from function $ids');
return ids;
});
});
}
Now _getIdsList() is working fine and the
when complete print('ids from function $ids');
line, prints the IDs List and I'm unable to understand why it doesn't work in my initState. Can anyone tell me what's wrong with my code?

Flutter Future always return null

What is wrong in my code it always returns null
getLocation().then((r) {
if (r != null) {
print("r=" + r.length.toString());
} else {
print("result is null");
}
});
Future< List<double>> getLocation() async {
// print("getLocation called");
location = new Location();
List<double> result=[];
location.getLocation().then((loc) {
result.add(loc.latitude);
result.add(loc.longitude);
result.add(4213);
// print(loc.latitude.toString() + "," + loc.longitude.toString() +" l="+l1.length.toString());
return result;
}).catchError((e){
return result;
});
}
You are not returning anything in your function, only in your then callback.
Since you are using async syntax anyway you can just go for:
Future< List<double>> getLocation() async {
location = new Location();
List<double> result=[];
var loc = await location.getLocation();
result.add(loc.latitude);
result.add(loc.longitude);
result.add(4213);
return result;
}
I've taking error handling out of the code but you can just use try-catch if you want that.