Flutter:Flutter 应用程序中 Google 地图 API 的 Firebase 实时更新

Flutter: Firebase realtime updates for Google Maps API in a Flutter App

我正在开发一个 Google 基于地图的 flutter 应用程序。 这个应用程序应该发生的事情是,当用户向地图添加标记时,它应该为所有用户实时显示标记。在 firebase Firestore 中,标记将保存为标记模型。因此,当将新模型添加到 firestore 集合时,它应该更新所有用户地图。 我试图为此使用 flutter Streambuilder。根据 this firebase 文档 link,我可以实时显示来自 firebase 的所有文档。 我用这个 在地图上添加标记。

//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(),
        );
      },
    );
  }
}

根据以下代码,我尝试使用该逻辑来捕获数据并将其更新到我已经定义的集合中。根据以下代码,如果捕获到该数据,打印语句应给出一条控制台消息。问题是,没有控制台消息出现。我已经有一个使用 GoogleMap 制作的单独应用程序,我们可以使用它来设置标记并在 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),
              );
            },
          );
        },
      ),
    );
  }

在地图上添加标记,上传到地图中的标记就可以了。问题是使用该 streambuilder 获取实时文档不起作用。我正在使用 streambuilder,因为它在文档中提供。如果有任何其他方法可以获得 google 地图 API 的实时更新,可以在这种情况下使用,请也提出这些建议。

您需要使用.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);
});