I am working on a Google map based flutter app. What should happen in this app is, when a user adds a marker to the map it should real-time show the marker for all the users. In the firebase firestore, markers will be saved as marker models. So when a new model is added to the firestore collection, it should update all user maps. I was trying to use fluter Streambuilder for that. According to this firebase documentation link, I can display all Documents from firebase in real-time. I used this link to add markers to the map.
//this part is directly from firebase.flutter.dev official docs
class UserInformation extends StatefulWidget {
@override
_UserInformationState createState() => _UserInformationState();
}
class _UserInformationState extends State<UserInformation> {
final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance.collection('users').snapshots();
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _usersStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
return ListView(
children: snapshot.data!.docs.map((DocumentSnapshot document) {
Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
return ListTile(
title: Text(data['full_name']),
subtitle: Text(data['company']),
);
}).toList(),
);
},
);
}
}
According to the following code I tried to use that logic to capture the data and update it in a set I defined already. According to the following code, if that data is captured, the print statement should give a console message. The problem is, there are no console messages appearing. I already have a separate app made with GoogleMap, where using that we can set markers and update those markers in firebase.
Completer<GoogleMapController> _controller = Completer();
static final CameraPosition _kGooglePlex = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746,
);
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection('markers').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Something went wrong');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Text("Loading");
}
snapshot.data!.docs.map((DocumentSnapshot document) {
print(document.toString());
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
MarkerModel model = MarkerModel(
markerId: document.id,
latitude: data['latitude'],
longitude: data['longitude'],
infoTitle: data['title'],
infoSnippet: data['snippet']);
Provider.of<MapScreenProvider>(context).addMarkerToSet(model);
});
return Consumer<MapScreenProvider>(
builder: (context, value, child) {
return GoogleMap(
markers: value.getMarkerSet,
padding: EdgeInsets.all(35),
mapType: MapType.normal,
onTap: (val) {
print(value.getMarkerSet.toString());
},
// onLongPress: (userPosition) async =>await saveMarker(userPosition, context),
initialCameraPosition: _kGooglePlex,
onMapCreated: (GoogleMapController controller) =>
_controller.complete(controller),
);
},
);
},
),
);
}
Adding markers to the map, those markers uploading in the map is fine. The issue is that using that streambuilder to get real-time docs is not working. I am using streambuilder because that is provided in the docs. if there are any other ways to get real-time updates for a google maps API, which can be used in this scenario pls suggest those too.
CodePudding user response:
You need to use .forEach and not .map.
snapshot.data!.docs.forEach((DocumentSnapshot document) {
print(document.toString());
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
MarkerModel model = MarkerModel(
markerId: document.id,
latitude: data['latitude'],
longitude: data['longitude'],
infoTitle: data['title'],
infoSnippet: data['snippet']);
Provider.of<MapScreenProvider>(context).addMarkerToSet(model);
});