I have an application where i need to get user real time location and push it into database using geoflutterfire , the code is working but i do not understand why it keeps generating multiple documents , while on the other side using the same plugin , we should use only collection reference , can any help me with this , Thank you
Picture showing pushing data into firestore using geoflutterfire plugin ( but why it keeps
generating new documents , i just want to solely update the same document )
Push data into firebase firestore
void updateDriverLocation(){
Fluttertoast.showToast(msg: "Called");
geoFlutterFire = Geoflutterfire();
if(latitude != 0.0 && longitude != 0.0){
GeoFirePoint geoFirePoint = geoFlutterFire.point(latitude: latitude, longitude: longitude);
var map = HashMap<String,Object>();
map['name'] = _firebaseAuth.currentUser!.uid;
map['position'] = geoFirePoint.data;
_firebaseFirestore.collection("Drivers").add(map);
}
}
get data from firebase firebase
void getDrivers(){
geoFlutterFire = Geoflutterfire();
GeoFirePoint geoFirePoint = GeoFirePoint(latitude, longitude);
var ref = _firebaseFirestore.collection('Drivers');
var locations = geoFlutterFire.collection(collectionRef: ref).within(center: geoFirePoint, radius: maxRadius, field: 'position');
locations.listen((List<DocumentSnapshot> documentList) {
for (var documentSnapshot in documentList) {
Map<String,Object> map = documentSnapshot.get('geopoint');
double lat = map['latitude'] as double;
double lon = map['longitude'] as double;
//_list.add(LatLng(lat, lon));
markers.add(Marker(
markerId: MarkerId(DateTime.now().millisecond.toString()),
position: LatLng(lat,lon),
icon: BitmapDescriptor.defaultMarker
));
}
});
}
This is how i'm trying to listen to the data returned from firestore
_firebaseFirestore.collection("Drivers").add(map);
The .add() method creates a new document with a random ID every time. If you want to update a specific document then you must use update() on a DocumentReference. Try the following:
_firebaseFirestore.collection("Drivers").doc(_firebaseAuth.currentUser!.uid).update(map);
This will update current drivers document only.
GeoFlutterFire has the following to specify DocID:
geoRef.setDoc(String id, var data, {bool merge})
Related
I want to fetch address to show on google map. I can only do address with lat,lng. Name of home address, road, sub-district, city, but I tried many ways and it's not showing up. Please help.
I'll have it written in the else section.
#override
void initState() {
findLocation();
super.initState();
}
LatLng centerMap = LatLng(1232,213123, 123.123213);
void findLocation() async {
var lat = double.tryParse(searchitems[0].address![widget.index].latitude.toString());
var lng = double.tryParse(searchitems[0].address![widget.index].longitude.toString());
if (lat != null && lng != null) {
centerMap = LatLng(lat, lng);
} else {
}
print("map:$centerMap");
}
If you want to get address by lattiude and longitude then you can use Google's API for finding the address.
For that, first you have to generate a key from Google Cloud Platform and enable the Geocoding API from it. Then you can fetch address this way:
getAddressFromLatLng(context, double lat, double lng) async {
String _host = 'https://maps.google.com/maps/api/geocode/json';
final url = '$_host?key=$mapApiKey&language=en&latlng=$lat,$lng';
if(lat != null && lng != null){
var response = await http.get(Uri.parse(url));
if(response.statusCode == 200) {
Map data = jsonDecode(response.body);
String _formattedAddress = data["results"][0]["formatted_address"];
print("response ==== $_formattedAddress");
return _formattedAddress;
} else return null;
} else return null;
}
Now if you want to get lat-long by address, you can do it in following way. You can add this package called geocoder:
(from source)
import 'package:geocoder/geocoder.dart';
// From a query
final query = "1600 Amphiteatre Parkway, Mountain View";
var addresses = await Geocoder.local.findAddressesFromQuery(query);
var first = addresses.first;
print("${first.featureName} : ${first.coordinates}");
There's also a package called geocoding(link). You can try that too.
We are trying to loop through a set of documents in Firestore that are geo based, though the query only appears to be returning the last result and we cannot work out why
Future fetchTasksNearBy(double lat, double lng) async {
debugPrint('getting tasks in location');
GeoFirePoint center = geo.point(latitude: lat, longitude: lng);
double radius = 70; //in km
String field = 'location';
// Reading nearby tasks based on lat, lng parameters
try {
// Collection ref
var collectionReference = tasksRef.where('status', isEqualTo: 'Posted');
var geoRef = geo.collection(collectionRef: collectionReference);
Stream<List<DocumentSnapshot>> placesStream = geoRef.within(
center: center,
radius: radius,
field: field,
strictMode: true,
); // = false includes borderline places
await for (var doclist in placesStream) {
for (DocumentSnapshot ds in doclist) {
GeoPoint point = ds['location']['geopoint'];
_tasks.add(Task.fromDoc(ds));
return _tasks;
}
}
} catch (e) {
throw Exception(e);
}
}
I want to put extra data at node in database this node is created using geofire and when i try to put this information is appear at database then hide like below,
availableDrivers
3gDKSbnMEBYZsZDwL6lmiQerP9P2
g:
"stq5ncg7kr"
l
0: 30.0688058
1: 31.2387825
I want to add extra information like
availableDrivers
3gDKSbnMEBYZsZDwL6lmiQerP9P2
g:
"stq5ncg7kr"
l
0: 30.0688058
1: 31.2387825
name: bishoy
age: 24
they added but then hide or removed, below my code.
main
DatabaseReference adminRef = FirebaseDatabase.instance.reference().child("admin");
DatabaseReference driversRef = FirebaseDatabase.instance.reference().child("drivers");
DatabaseReference newRequestRef = FirebaseDatabase.instance.reference().child("Ride Request");
DatabaseReference rideRequestRef = FirebaseDatabase.instance.reference().child("drivers").child(currentfirebaseUser!.uid).child("newRide");
DatabaseReference availableDriver = FirebaseDatabase.instance.reference().child("availableDrivers").child(currentfirebaseUser!.uid);
function that generate availabledriver and I put my extra information their
void makeDriverOnlineNow() async
{
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
currentPosition = position;
Map<String, dynamic> driverMap = {
"name" : driversInformation!.name,
"phone" : driversInformation!.phone,
};
Geofire.initialize("availableDrivers");
Geofire.setLocation(currentfirebaseUser!.uid, currentPosition!.latitude, currentPosition!.longitude);
await availableDriver.update(driverMap);
rideRequestRef.set("searching");
rideRequestRef.onValue.listen((event) {
});
}
void getLocationLiveUpdates()
{
homeTabPageStreamSubscription = Geolocator.getPositionStream().listen((Position position)
{
currentPosition = position;
if(isDriverAvailable == true)
{
Geofire.setLocation(currentfirebaseUser!.uid, position.latitude, position.longitude);
}
LatLng latLng = LatLng(position.latitude, position.longitude);
newcontrollerGoogleMap!.animateCamera(CameraUpdate.newLatLng(latLng));
});
}
It looks like it is not possible in the flutter_geofire to add your own data to the node that it manages. Of the GeoFire implementations that Firebase itself delivers only the Android library allows you to add your own data to the geolocation node, and I'll admit to not being a big fan of it.
To keep your own data, set up you database like this:
driverLocations: {
// geolocation data, managed by geofire
"3gDKSbnMEBYZsZDwL6lmiQerP9P2": {
"g": "stq5ncg7kr",
"l": [30.0688058, 31.2387825]
}
},
drivers: {
// driver properties, managed by you
"3gDKSbnMEBYZsZDwL6lmiQerP9P2": {
name: "bishoy",
age: 24
}
}
}
Now it is clear what data is managed by whom, and you'll typically only access the driverLocations data through GeoFire. Once you get the key of a driver from GeoFire, you can look up their properties from /drivers/$key. Doing this for multiple drivers is not as slow as you may initially expect, because Firebase pipelines the requests over a single WebSocket connection.
I am trying to fetch all the conferences that contain current user's uid. I am trying to accomplish it by using OrderByChild($string).(firebaseauth.currentuser.uid) as show below in my codes. In my codes, i fetched the current users specific key in string and then used it to fetch all the data that contain that key.
String MyAssigningID = "...";
Future<void> _fetchUserASSIGNINGIDFromDatabase() async {
DatabaseReference reference = FirebaseDatabase.instance.reference().child("User").child(widget.GroupID).child("Group-Members").child(auth.currentUser.uid);
final DataSnapshot data = await reference.once();
setState(() {
MyAssigningID = data.value['AssigningID'].toString();
});
}
GetGroupFunction() {
DatabaseReference referenceData = FirebaseDatabase.instance.reference().child("User").child(widget.GroupID).child("Conferences");
referenceData.orderByChild(MyAssigningID).equalTo(auth.currentUser.uid).once().then((DataSnapshot dataSnapshot) {
Conferencelists.clear();
var keys = dataSnapshot.value.keys;
var values = dataSnapshot.value;
for (var key in keys) {
Conferencemodals conferencemodals = new Conferencemodals
(
values [key]['Title'],
values [key]['Description'],
values [key]['StartingTime'],
values [key]['EndingTime'],
values [key]['Duration'],
values [key]['ConferenceID'],
values [key]['SchoolUpin'],
values [key]['CreatedDate'],
values [key]['Published'],
values [key]['ConferenceDay'],
values [key]['ConferenceHost'],
);
Conferencelists.add(conferencemodals);
}
setState(() {
TotalConferences = Conferencelists.length.toString();
});
});
}
I can create a Google map that centers on Niwot, CO using geocode. If I click the "Encode" button from the form (which I got from Google's website), it puts a marker on the map in the correct location.
My question is: How do I retrieve the position coordinates (latitude and longitude) using the javascript callback function? I need to put the lat and long into my database.
Also, right now I'm using this for just one place for troubleshooting, but I'll then need it for numerous addresses.
Code is below.
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(40.171776, -105.116737);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function codeAddress() {
var address = 'Niwot, CO';//this will eventually be an array
geocoder.geocode( { 'address': address}, function(results) {
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
//code below added based on comment 1; how do I display that lat and lng? I'll need to do this for troubleshooting.
var latlng = results[0].geometry.location;
var lat = latlng.lat();
var lng = latlng.lng();
});
}
The location returned is an instance of the LatLng class. You can call lat() to get the latitude and lng() to get the longitude. e.g.
var latlng = results[0].geometry.location;
var lat = latlng.lat();
var lng = latlng.lng();
Here are the relevant docs:
http://code.google.com/apis/maps/documentation/javascript/reference.html#LatLng
You can do that inside your geocode call
geocoder.geocode( { 'address': 'CA, US'}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
location = results[0].geometry.location;
alert(location)
}
});
This will show the latitude and longitude of the address.
(lat,lng)