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

Firestore多层测试数据存储优化及快速加载方案咨询

优化Firestore测试数据存储与加载性能

问题背景

当前场景为多测试、每测试包含多个问题、每个问题带多个选项,数据层级为「Test 1 > q1、q2、q3... > question: hello, answer: opt 2, opt 1: a, opt 2: b, opt 3: c, opt 4: d」。使用以下代码写入Firestore时加载延迟严重,需优化存储结构实现测试快速加载:

for (var i = 1; i < totalquestions + 1; i++) {
  await FirebaseFirestore.instance
      .collection("users")
      .doc(user!.uid)
      .collection('Test $no')
      .doc(i.toString())
      .set(
        Map<String, dynamic>.from(
          Provider.of<Question>(context, listen: false)
              .question[i]!,
        ),
      );
  await FirebaseFirestore.instance
      .collection("users")
      .doc(user.uid)
      .collection('Test $no')
      .doc(i.toString())
      .update(
    {
      'yourAns':
          Provider.of<Question>(context, listen: false)
              .answers[i]!
              .values
              .first
    },
  );
}

优化方案

1. 合并写入操作,减少网络请求

原代码每个问题都执行set+update两次独立请求,循环N次就会产生2N次网络调用,这是延迟的核心原因。直接把yourAns字段整合到初始写入的Map里,一次完成数据提交:

for (var i = 1; i < totalquestions + 1; i++) {
  // 合并问题数据和用户答案
  Map<String, dynamic> questionData = Map<String, dynamic>.from(
    Provider.of<Question>(context, listen: false).question[i]!,
  );
  questionData['yourAns'] = Provider.of<Question>(context, listen: false)
      .answers[i]!
      .values
      .first;

  await FirebaseFirestore.instance
      .collection("users")
      .doc(user!.uid)
      .collection('Test $no')
      .doc(i.toString())
      .set(questionData);
}

2. 调整数据结构,减少文档数量

不要给每个问题单独创建文档,而是把整个测试的所有问题数据放到单个文档中。这样加载测试时只需要读取一次文档就能获取全部内容,大幅降低网络交互次数:

// 写入整个测试数据到单个文档
await FirebaseFirestore.instance
    .collection("users")
    .doc(user!.uid)
    .collection("tests") // 统一用tests集合管理所有测试
    .doc('Test $no')
    .set({
  'questions': Provider.of<Question>(context, listen: false).question.values.toList(),
  'userAnswers': Provider.of<Question>(context, listen: false).answers.map((key, val) => MapEntry(key, val.values.first))
});

读取时只需获取该文档,解析里面的questions数组和userAnswers对象即可,加载速度会显著提升。

3. 使用批量写入(Batched Writes)

如果必须保留“每个问题一个文档”的结构,改用Firestore的批量写入功能,把多个写入请求合并为一次提交,减少网络往返开销:

WriteBatch batch = FirebaseFirestore.instance.batch();
CollectionReference testCol = FirebaseFirestore.instance
    .collection("users")
    .doc(user!.uid)
    .collection('Test $no');

for (var i = 1; i < totalquestions + 1; i++) {
  DocumentReference docRef = testCol.doc(i.toString());
  Map<String, dynamic> data = Map<String, dynamic>.from(
    Provider.of<Question>(context, listen: false).question[i]!,
  );
  data['yourAns'] = Provider.of<Question>(context, listen: false)
      .answers[i]!
      .values
      .first;
  batch.set(docRef, data);
}

// 一次性提交所有操作
await batch.commit();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:40:11