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
Related
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);
}
}
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?
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;
}
}
I'm trying to call a function which will populate a list by reading a stream. Means, it will read a stream and add values to a list and finally, the list will be returned by the function.
The problem is, when I'm using await for to read the stream, the code after the await for is not getting executed. And I tried to use listen, then it's not waiting to finish reading the stream. The code after the listen is getting executed even before the stream is read completely.
Following in my code -
Future<List<Map<String, dynamic>>> getNearestDriver(Stream<List<DocumentSnapshot>> driverWithinRangeStream, GeoPoint source) async {
print("Get Nearest Driver Called");
List<Map<String, dynamic>> driverAvailableList = [];
await for (List<DocumentSnapshot> documentList in driverWithinRangeStream){
documentList.forEach((DocumentSnapshot document) async {
String driverIDVar = document.data['driverid'];
GeoPoint pos = document.data['position']['geopoint'];
var point = geo.point(latitude: pos.latitude, longitude: pos.longitude);
double distanceVar = point.distance(lat: source.latitude, lng: source.longitude);
int distanceInMeter = (distanceVar*1000).round();
Map<String, dynamic> newDriverAvailable = {"driverId": driverIDVar, "distance" : distanceInMeter};
driverAvailableList.add(newDriverAvailable);
});
print(driverAvailableList); /* <- I get the data here */
}
print(driverAvailableList); /* <- But I don't get the data here. This code is not even being executed. */
}
Please let me know what's wrong here.
Would you mind to try
try{
await for (List<DocumentSnapshot> documentList in driverWithinRangeStream){
await Future.forEach(documentList, (DocumentSnapshot document) async {
try{
String driverIDVar = document.data['driverid'];
GeoPoint pos = document.data['position']['geopoint'];
var point = geo.point(latitude: pos.latitude, longitude: pos.longitude);
double distanceVar = point.distance(lat: source.latitude, lng: source.longitude);
int distanceInMeter = (distanceVar*1000).round();
Map<String, dynamic> newDriverAvailable = {"driverId": driverIDVar, "distance" : distanceInMeter};
driverAvailableList.add(newDriverAvailable);
}catch(error){
throw "throw from documentList, Error:$error";}
});
}
}catch(error){
print ("catch in driverWithinRangeStream, Error:$error");}
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?