I have this code trying to query some data from Firestore using GeoFlutterFire, but for the sake of efficiency I want to fetch the list of ids only once, then use it to fetch the rest of the data from Firebase Database.
This is the code in question:
class _StartScreenState extends State<StartScreen> {
List ids = ['abc'];
#override
void initState() {
super.initState();
print('ids ${ids}');
}
_initState() async {
Firestore _firestore = Firestore.instance;
List ids1 = [];
Geoflutterfire geo = Geoflutterfire();
var location = new Location();
var pos = await location.getLocation();
GeoFirePoint center = geo.point(latitude: pos.latitude.toDouble(), longitude: pos.longitude.toDouble());
var collectionReference = _firestore.collection('locations');
var geoRef = geo.collection(collectionRef: collectionReference);
return ids1.add(geoRef.within(center: center, radius: 50, field: 'position', strictMode: true).first.then((value) {
value.map((doc) {
if (doc.data.isNotEmpty) {
print('doooc id here ${doc['id']}');
ids1.add(doc['id']);
print(ids1);
}
}).toList();
setState(() {
ids = ids1;
print('setting state to ids ids print: ${ids.}');
});
}));
}
Like I said, my intent is to fetch the Ids and once I have the list check if there's some related data in Firebase, but I'm not sure this is the way I should do it and there's something that I don't know how to awoid; When I print the list I get the following result:
setting state to ids ids print: [Instance of 'Future',
3esdWesqrTD_123_3dssds3, sQWdsda23dsad_da21]
Can anyone tell me why I have this Instance of 'Future' in my List and how can avoid it, please?
I have not tried to run your code, but I suspect the issue starts with the statement
return ids1.add(geoRef.within(center: center, radius: 50, field: 'position', strictMode: true).first.then((value) {
As you can see, you are adding something ids1.add(...) that looks like it needs to await: geoRef.within(...).first.(...). I don't find the ids1.add(...) call needed in the return statement. Try removing it, and see how it goes.
Related
I'm a total noob with flutter and I'm trying to create an app that shows me some markers on a map pointing the location of the soccer fields and only this.
enter image description here
Currently i have the google map marks all the places nearby. I did this using the google Nearvy places API. So I need it to only mark the nearby soccer fields, but this option does not appear in the type section.
This is the code that I use to use the google api. As u seen in the url, the word soccer in type does not work.
Future<dynamic> getPlaceDetails(LatLng coords, int radius) async {
var lat = coords.latitude;
var lng = coords.longitude;
final String url =
'https://maps.googleapis.com/maps/api/place/nearbysearch/json?&location=$lat,$lng&radius=$radius&type=soccer&key=$key';
var response = await http.get(Uri.parse(url));
var json = convert.jsonDecode(response.body);
return json;
}
This is the method I use to mark the nearvy places
void maracaCanchas() {
if (_debounce?.isActive ?? false) _debounce?.cancel();
_debounce = Timer(Duration(seconds: 2), () async {
var placesResult =
await MapServices().getPlaceDetails(tappedPoint, radiusValue.toInt());
List<dynamic> placesWithin = placesResult['results'] as List;
allFavoritePlaces = placesWithin;
tokenKey = placesResult['next_page_token'] ?? 'none';
_markers = {};
placesWithin.forEach((element) {
_setNearMarker(
LatLng(element['geometry']['location']['lat'],
element['geometry']['location']['lng']),
element['name'],
element['types'],
element['business_status'] ?? 'not available',
);
});
_markersDupe = _markers;
pressedNear = true;
_setLocationMarker();
});
}
Please help me.
I am trying to mark only soccer fields on the map, but it brings me all the places
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 these 2 collection with a users collection and i want to make a list of providers for one user
i tried this code but not give me results :(
Future<List<ServineraProvider>> getfavoritesForUser() async{
List<ServineraProvider> providers = [];
await providerSkillsCollection.where('providerID', isEqualTo: this.uid).get()
.then((onValue){
for(int i=0; i<onValue.docs.length; i++){
var doc = onValue.docs[i].data() as Map<String,dynamic>;
print(doc['skillID']);
skillsCollection.doc(doc['skillID']).get()
.then((doc){
var data = doc.data() as Map<String,dynamic>;
providers.add(ServineraProvider(
providerID: data['providerID'],
providerName: data['providerName'],
providerEmail: data['providerEmail'],
providerPhoneNumber: data['providerPhoneNumber'],
providerPicture: data['providerPicture'],
providerState: data['providerState'],
providerStatus: data['providerStatus']
)
);
});
}
});
return providers;
}
i know there is a mistake but can't solve
You're combining then with await, which is almost never a good idea. In this case it results in returning the providers list after the providerSkillsCollection query has completed, but before any of the providers themselves have been loaded.
To solve the problem with just await:
Future<List<ServineraProvider>> getfavoritesForUser() async{
List<ServineraProvider> providers = [];
var onValue = await providerSkillsCollection.where('providerID', isEqualTo: this.uid).get()
for(int i=0; i<onValue.docs.length; i++){
var doc = onValue.docs[i].data() as Map<String,dynamic>;
print(doc['skillID']);
var doc = await skillsCollection.doc(doc['skillID']).get()
var data = doc.data() as Map<String,dynamic>;
providers.add(ServineraProvider(
providerID: data['providerID'],
providerName: data['providerName'],
providerEmail: data['providerEmail'],
providerPhoneNumber: data['providerPhoneNumber'],
providerPicture: data['providerPicture'],
providerState: data['providerState'],
providerStatus: data['providerStatus']
));
}
return providers;
}
I'm getting an error: The argument type 'Query<Object?>' can't be assigned to the parameter type 'Query<Map<String, dynamic>>'. I'm fairly new to Flutter, and I'm trying to update some code to the latest Flutter/Dart and plugins. It looks like it's happening during the usersQuery, and all the documentation is somewhat esoteric to me, unfortunately(granted, if its anything like last time, I'll sleep a couple of days and then end up smacking myself in the forehead because it was something simple I just happened to miss). Any help would be appreciated. The error is on : final allUsers = await geo
.collection(collectionRef: usersQuery)
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:dating_app/constants/constants.dart';
import 'package:dating_app/models/user_model.dart';
import 'package:geoflutterfire/geoflutterfire.dart';
class UsersApi {
/// Get firestore instance
///
final _firestore = FirebaseFirestore.instance;
/// Get all users
Future<List<DocumentSnapshot<Map<String, dynamic>>>> getUsers({
required List<DocumentSnapshot<Map<String, dynamic>>> dislikedUsers,
}) async {
/// Build Users query
Query usersQuery = _firestore
.collection(C_USERS)
.where(USER_STATUS, isEqualTo: 'active')
.where(USER_LEVEL, isEqualTo: 'user');
// Filter the User Gender
usersQuery = UserModel().filterUserLooking(usersQuery);
// Instance of Geoflutterfire
final Geoflutterfire geo = Geoflutterfire();
/// Get user settings
final Map<String, dynamic>? settings = UserModel().user.userSettings;
// // Get user geo center
final GeoFirePoint center = geo.point(
latitude: UserModel().user.userGeoPoint.latitude,
longitude: UserModel().user.userGeoPoint.longitude);
final allUsers = await geo
.collection(collectionRef: usersQuery)
.within(
center: center,
radius: settings![USER_MAX_DISTANCE].toDouble(),
field: USER_GEO_POINT,
strictMode: true)
.first;
Use this :
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:dating_app/constants/constants.dart';
import 'package:dating_app/models/user_model.dart';
import 'package:geoflutterfire/geoflutterfire.dart';
class UsersApi {
/// Get firestore instance
///
final _firestore = FirebaseFirestore.instance;
/// Get all users
Future<List<dynamic> getUsers({
required List<dynamic> dislikedUsers,
}) async {
/// Build Users query
Query usersQuery = _firestore
.collection(C_USERS)
.where(USER_STATUS, isEqualTo: 'active')
.where(USER_LEVEL, isEqualTo: 'user');
// Filter the User Gender
usersQuery = UserModel().filterUserLooking(usersQuery);
// Instance of Geoflutterfire
final Geoflutterfire geo = Geoflutterfire();
/// Get user settings
var settings = UserModel().user.userSettings;
// // Get user geo center
final GeoFirePoint center = geo.point(
latitude: UserModel().user.userGeoPoint.latitude,
longitude: UserModel().user.userGeoPoint.longitude);
final allUsers = await geo
.collection(collectionRef: usersQuery)
.within(
center: center,
radius: settings![USER_MAX_DISTANCE].toDouble(),
field: USER_GEO_POINT,
strictMode: true)
.first;
Hope this will work
I need to retrieve a document from the 'announcements' collection of my document. Each of the documents in the collection is named a day of the year, for example '2020-07-02'. I want to retrieve the document for the current day. In the document, I need to access a map array titled 'details' containing the various announcements. How would I write that into my app? Here is what I am doing currently, but I don't know where to go from there.
Future getAnnouncements() async {
var currentDate = DateFormat("yyyy-MM-dd").format(DateTime.now());
var firestore = Firestore.instance;
Stream<DocumentSnapshot> qn = firerestore.collection('announcements').document(currentDate).snapshots();
return qn; //I want to only return the map array of the various documents
}
Try this
Future getAnnouncements() async {
var currentDate = DateFormat("yyyy-MM-dd").format(DateTime.now());
var firestore = Firestore.instance;
Future<DocumentSnapshot> qn = await firerestore.collection('announcements')
.document(currentDate)
.get();
return List<Map>.castFrom(qn["details"]);
}
To parse through the returned List, you could try this
List<Map> retrievedData = await getAnnouncements();
for(int i = 0; i < retrievedData.length; i++)
{
print(retrievedData[i]["title"]);
print(retrievedData[i]["text"]); // Thanks #VLXU
}