从flutter / firebase中的多个文档中获取项目的串联列表

时间:2019-12-04 08:43:43

标签: firebase flutter google-cloud-firestore

我有一个Firebase数据库,其中有一个名为“测验”的集合,其中每个测验是一个文档,其中包含几个问题。

现在,我正在尝试从多个“测验”文档中创建一个列表问题,然后将其以混乱的方式传递给综合浏览量生成器。

但是,我在扑朔迷离中无法从多个文档中获取项目列表。该代码一直工作到可以从各个主题获得测验列表的地步,如下所示,但是当我尝试使用下面的两个函数获取项目列表时,最后仍然会得到一个空列表。

我不熟悉Flutter和异步编程。任何帮助是极大的赞赏。


class PracticeScreen extends StatelessWidget {

  List<Question> questions = [];

 @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      builder: (_) => QuizState2(),
      child: FutureBuilder(
        future: Global.topicsRef.getData(),
        builder: (BuildContext context, AsyncSnapshot snap) {
          var state = Provider.of<QuizState2>(context);

          if (!snap.hasData || snap.hasError) {
            return LoadingScreen();
          } else {
            List<Topic> topics = snap.data;
            List<Quiz> quizzes =
                topics.map((topic) => topic.quizzes).expand((x) => x).toList();

            print(quizzes.length);
            print(quizzes.map((quiz) => quiz.description).toList());

// the code works till this point where I get a list of quizzes from multiple topics
            quizzes.map((quiz) => _getQuestions3(quiz.id));

// the questions array still remains empty at this point. 
            print(questions.map((question) => question.text).toList());

            return Scaffold(
              body: PageView.builder(
                physics: NeverScrollableScrollPhysics(),
                scrollDirection: Axis.vertical,
                controller: state.controller,
                onPageChanged: (int idx) =>
                    state.progress = (idx / (questions.length + 1)),
                itemBuilder: (BuildContext context, int idx) {
                  //return Text('Sample');
                  return QuestionPage2(question: questions[idx]);
                },
                itemCount: questions.length - 1,
              ),
              bottomNavigationBar: AppBottomNav(),
            );

          }
        },
      ),
    );
  }

  _getQuestions2(String quizId) async {
    Future quizData = Document<Quiz>(path: 'quizzes/$quizId').getData();
    quizData.then((quizdata) {
      questions = questions..addAll(quizdata.questions.toList());
    });
  }

  _getQuestions3(String quizId) async {
    await _getQuestions2(quizId);
  }
}
}

2 个答案:

答案 0 :(得分:0)

我认为以下一行是错误的:

questions = questions..addAll(quizdata.questions.toList());

每个Dart/Flutter documentation addAll函数是所谓的void函数。这意味着它只会执行此工作,之后不会返回任何内容。

questions..addAll()将quizdata添加到问题列表中,但不返回任何内容(null)。通过调用questions = questions..addAll(),您基本上可以用null覆盖问题列表。

替换

questions = questions..addAll(quizdata.questions.toList());

使用以下行来解决此问题:

questions.addAll(quizdata.questions.toList());

整个功能应如下所示:

_getQuestions2(String quizId) async {
  Future quizData = Document<Quiz>(path: 'quizzes/$quizId').getData();
  quizData.then((quizdata) {
    questions.addAll(quizdata.questions.toList());
  });
}

答案 1 :(得分:0)

这就是最终为我工作的原因。

我认为在一个异步函数中包含多个firestone查询比尝试通过多个函数要容易得多。

 Future<List<Question>> getQuestions() async {
    var firestore = Firestore.instance;
    var topicsSnap = await firestore.collection('topics').getDocuments();
    var quizzes =
        (topicsSnap.documents.map((topic) => topic.data['quizzes'])).toList();
    var quizids = quizzes.map((quizitem) => quizitem[0]['id']).toList();
    var questions = [];
    for (int i = 0; i < quizids.length; i++) {
      var quizid = quizids[i];
      var quizsnap = await firestore.document('quizzes/$quizid').get();
      var quizQuestions = quizsnap.data['questions'];
      questions.addAll(quizQuestions);
    }
    var question2 = questions.map((v) => Question.fromMap(v)).toList();
    return (question2);
  }