Firebase Firestore 和 Google 地图自定义标记仅显示一个标记

Firebase Firestore and Google Maps Custom Marker only showing one marker

我正在尝试使用插件 Custom Marker 在 google 地图上显示,我已经快要工作了,但它只显示我模型中的一个标记,而我希望它显示所有他们中的。为什么 firestore 只显示一个标记,我如何获得完整列表以显示所有标记而不是只显示一个标记?

编辑 1:删除了旧的创建标记功能,该功能用于制作正常的 google 地图标记。现在剩下的就是功能代码,它只显示一个标记而不是整个列表。

编辑 2:在查看了下面的初步建议后,我意识到我收到了与他们的建议类似的错误消息。

编辑 3:根据@Denzel 的建议,工作代码位于底部

未处理的异常:setState() 回调参数返回了 Future。 E/flutter (31835):使用返回 Future 的闭包或方法调用了 _HomePageState#73fe9 上的 setState() 方法。也许它被标记为“异步”。 E/flutter (31835):不是在对 setState() 的调用中执行异步工作,而是先执行工作(不更新小部件状态),然后在对 setState() 的调用中同步更新状态。


import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:custom_marker/marker_icon.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter/material.dart';

import '../models/marker_collect_model.dart';

class CustomMarkies extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<CustomMarkies> {
  Set<Marker> list = <Marker>{};
  List<String> listDocuments = [];

  Future<void> readDataFromFirebase() async {
    FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference<Map<String, dynamic>> collectionReference =
    firestore.collection('2022TABR');
    collectionReference.snapshots().listen((event) {
      List<DocumentSnapshot> snapshots = event.docs;
      for (var map in snapshots) {
        Map<String, dynamic> data =
        map.data() as Map<String, dynamic>; // add this line
        MarkerCollectModel model =
        MarkerCollectModel.fromMap(data); // use data here
        String nameDocument = map.id;
        listDocuments.add(nameDocument);
        setState(() async {
          Random random = Random();
          int i = random.nextInt(10000);
          String idString = 'id$i';
          list.add(Marker(
            markerId: MarkerId(idString),
            icon: await MarkerIcon.downloadResizePicture(
                url: model.urlavatar!, imageSize: 250),
            position: LatLng(model.lat!, model.lng!),
          );
        });
      }
    });
  }
  
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GoogleMap(
        initialCameraPosition: CameraPosition(target: LatLng(45.4279, -123.6880), zoom: 3),
        markers: list,
      ),
      floatingActionButton: FloatingActionButton.extended(
        label: FittedBox(child: Text('Add Markers')),
        onPressed: () async {
          readDataFromFirebase();
          list.toSet();
          setState(() {});
        },
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

工作代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:custom_marker/marker_icon.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:flutter/material.dart';

import '../models/marker_collect_model.dart';

class CustomMarkies extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<CustomMarkies> {
  Set<Marker> list = <Marker>{};
  List<String> listDocuments = [];

  Future<void> readDataFromFirebase() async {
    FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference<Map<String, dynamic>> collectionReference =
    firestore.collection('2022TABR');
    collectionReference.snapshots().listen((event) async {
      List<DocumentSnapshot> snapshots = event.docs;
      for (var map in snapshots) {
        Map<String, dynamic> data =
        map.data() as Map<String, dynamic>; // add this line
        MarkerCollectModel model =
        MarkerCollectModel.fromMap(data); // use data here
        String nameDocument = map.id;
        listDocuments.add(nameDocument);
          list.add(Marker(
            markerId: MarkerId(nameDocument),
            icon: await MarkerIcon.downloadResizePicture(
                url: model.urlavatar!, imageSize: 250),
            position: LatLng(model.lat!, model.lng!),
          ));
      }
    });
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GoogleMap(
        initialCameraPosition: CameraPosition(target: LatLng(45.4279, -123.6880), zoom: 3),
        markers: list,
      ),
      floatingActionButton: FloatingActionButton.extended(
        label: FittedBox(child: Text('Add Markers')),
        onPressed: () async {
          readDataFromFirebase();
          list.toSet();
          setState(() {});
        },
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}
    class CustomMarkies extends StatefulWidget {
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<CustomMarkies> {
      Set<Marker> list = <Marker>{};
      List<String> listDocuments = [];
    
      /// This [async] here covers for everything within the function,
      /// You can use [await] anywhere you want to
      /// [collectionReference.snapshots()] returns a [Stream], so you [listen] to it
      /// There's no need for [await] because [Stream] handles real-time data
      /// In essence, it would update all it's [listeners] about the new change and this change will take effect in your UI
      Future<void> readDataFromFirebase() async {
        FirebaseFirestore firestore = FirebaseFirestore.instance;
        CollectionReference<Map<String, dynamic>> collectionReference =
            firestore.collection('2022TABR');
        collectionReference.snapshots().listen((event) {
          for (var map in snapshots) {
            Map<String, dynamic> data =
            map.data() as Map<String, dynamic>; // add this line
            MarkerCollectModel model =
            MarkerCollectModel.fromMap(data); // use data here
            String nameDocument = map.id;
            listDocuments.add(nameDocument);
              list.add(Marker(
                markerId: MarkerId(nameDocument),
                icon: await MarkerIcon.downloadResizePicture(
                    url: model.urlavatar!, imageSize: 250),
                position: LatLng(model.lat!, model.lng!),
              ));
          }
        });
      }
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: GoogleMap(
            initialCameraPosition:
                CameraPosition(target: LatLng(45.4279, -123.6880), zoom: 3),
            markers: list,
          ),
          floatingActionButton: FloatingActionButton.extended(
            label: FittedBox(child: Text('Add Markers')),
            onPressed: () async {
// you have to `await readDataFromFirebase()` because it is a future.
              await readDataFromFirebase();
              list.toSet();
              setState(() {});
            },
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        );
      }
    }

我放评论进一步解释我的意思