我有一个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);
}
}
}
答案 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);
}