You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将列表元素按原序列保存至Firestore并维持顺序一致性

问题根源与解决方案

你遇到的问题其实不是列表被Firestore自动排序,而是Firestore的Map类型是无序的——你现在用站点名称作为Map的键来存储坐标,而Firestore会自动把Map的按键名升序排列,这才导致了顺序丢失。

接下来给你分步解决:

1. 理解问题本质

你的原代码里,initRoute是把每个站点的坐标以{站点名称: {Lat: ..., Lng: ...}}的Map形式存入Firestore。但Firestore的Map结构会自动按键的字母顺序重新排列,所以不管你添加的顺序是Mahsuri→Imperial→Garden,最终存储的Map键都会变成Garden→Imperial→Mahsuri,这就是顺序混乱的原因。

2. 修正方案:用有序数组替代Map

要保留原始顺序,你需要把站点信息存储为有序列表(数组),而不是Map。Firestore的数组是严格保留插入顺序的,完美适配你的Polyline需求。

修改后的代码如下:

List<String> _selectedBusStop = [];

Future<void> saveRoute() async {
  // 一次性获取所有匹配的站点文档(替代监听,因为你是保存数据,不需要实时更新)
  final snapshot = await Firestore.instance
      .collection('markers')
      .where('BusstopName', whereIn: _selectedBusStop)
      .get();

  if (snapshot.documents.isNotEmpty) {
    // 关键:按照_selectedBusStop的原始顺序重新排序获取到的文档
    final orderedDocuments = _selectedBusStop.map((busStopName) {
      return snapshot.documents.firstWhere(
        (doc) => doc['BusstopName'] == busStopName,
        orElse: () => null, // 处理找不到对应站点的情况
      );
    }).whereType<DocumentSnapshot>().toList();

    // 构建有序的站点信息列表
    final orderedRouteStops = orderedDocuments.map((doc) {
      return {
        'BusstopName': doc['BusstopName'],
        'Lat': doc['location'].latitude,
        'Lng': doc['location'].longitude,
      };
    }).toList();

    // 将有序列表存入Firestore
    await Firestore.instance.collection('routes').document(inputName).setData({
      'stops': orderedRouteStops, // 用数组存储,保留原始顺序
    }, merge: true);
  }

  setState(() {});
}

3. 代码说明

  • 用get()替代snapshots().listen():因为你是执行一次性的保存操作,不需要监听实时变化,单次获取更高效。
  • 手动排序文档:whereIn返回的结果顺序不一定和输入的_selectedBusStop一致,所以我们通过map+firstWhere把文档重新按原始顺序排列。
  • 用数组存储:把每个站点的完整信息(名称+坐标)做成一个对象,放到数组里,Firestore会完整保留这个数组的顺序。

4. 读取时的注意事项

之后读取这条路线时,直接从Firestore取出stops数组,它的顺序就是你保存时的原始顺序,直接用来生成Polyline就可以了。

内容的提问来源于stack exchange,提问作者randomstudent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 06:47:52