无法从嵌套集合中检索数据
Posted
技术标签:
【中文标题】无法从嵌套集合中检索数据【英文标题】:Cannot retrieve data from nested collection 【发布时间】:2022-01-07 01:16:03 【问题描述】:_getDataRowsForCompletedExerciseSets(workoutId) async
try
List listOfExercises = await FirebaseFirestore.instance
.collection('users')
.doc(currentUser!.uid)
.collection("workouts")
.doc(workoutId)
.collection("exercises")
.get()
.then((snapShot) => snapShot.docs);
for (int i = 0; i < listOfExercises.length; i++)
FirebaseFirestore.instance
.collection('users')
.doc(currentUser!.uid)
.collection("workouts")
.doc(workoutId)
.collection("exercises")
.doc(listOfExercises[i].doc.id.toString())
.collection("sets")
.snapshots()
.listen(_createListOfExerciseSets);
setState(()
for (ExerciseSet set in listOfExerciseSets)
//print(set.weight);
completedExerciseSetRows.add(DataRow(cells: [
DataCell(Text(setCount.toString())),
//const DataCell(VerticalDivider(thickness: 5)),
DataCell(Text(set.weight.toString())),
//const DataCell(VerticalDivider(thickness: 5)),
DataCell(Text(set.reps.toString())),
//const DataCell(VerticalDivider(thickness: 5)),
DataCell((isSetToFailure == true) ? Icon(Icons.check) : Icon(null))
//const DataCell(VerticalDivider(thickness: 5)),
]));
);
on Exception catch (_, e)
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(e.toString()),
duration: Duration(milliseconds: 1000),
),
);
return Container();
_createListOfExerciseSets(QuerySnapshot snapshot)
var docs = snapshot.docs;
for (var doc in docs)
listOfExerciseSets.add(ExerciseSet.fromFireStore(doc));
print('EXERCISE SETS = ' + listOfExerciseSets.toString());
我有以下数据库结构:
users-->id-->workouts-->id-->exercises-->id-->sets-->id--fields
我正在尝试获取特定锻炼(id)的练习以及每个练习的集合(包括字段)。 listOfExercises 始终为空(0 项)。也没有任何错误显示。
【问题讨论】:
请也分享您的 Json 响应。 什么json响应?很抱歉没有 json 响应。 我已经为 _createListOfExerciseSets 添加了代码;虽然 listOfExercises 与 listOfExerciseSets 不同。 在setState
中添加一些调试prints
,你会看到它们在prints
之前在_createListOfExerciseSets
中打印 - 这就是为什么你总是有空数据的原因
_createListOfExerciseSets 是在 _getDataRowsForCompletedExerciseSets 中调用 setState 之前调用的单独方法。如何在 _createListOfExerciseSets 中的 setState 之后添加打印?! _createListOfExerciseSets 中没有 setState。
【参考方案1】:
这是我现在拥有的:
Widget build(BuildContext context)
var exercisesRef = usersRef
.doc(currentUser!.uid)
.collection('workouts')
.doc(workoutId)
.collection('exercises');
return FutureBuilder<QuerySnapshot>(
future: exercisesRef.get(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot)
switch (snapshot.connectionState)
case ConnectionState.active:
return const Center(
child: kCPI,
);
case ConnectionState.waiting:
return const Center(
child: kCPI,
);
case ConnectionState.none:
return const Center(
child: kCPI,
);
case ConnectionState.done:
if (snapshot.hasError)
return Text('Error: $snapshot.error');
else if (!snapshot.hasData)
//print('WORKOUTID = ' + workoutId);
return const Text("Document does not exist");
else if (snapshot.hasData &&
snapshot.connectionState == ConnectionState.done)
final exercises = snapshot.data!.docs;
List<Widget> completedExercisesWidgetsList = [];
final _controller = ScrollController();
// for loop - loop through all the exercises for the current workout
for (var doc in exercises)
bool isRowsGeneratedForPreviousExercises = false;
dataRowsForCompletedExercises = [];
var setList = [];
Map<String, dynamic> exercise;
var exerciseName = '';
exercise = doc.data() as Map<String, dynamic>;
setList = exercise['sets'];
exerciseName = exercise['name'];
//loop through the sets for the exercise
for (var set in setList)
var setNumber = 0;
var weight = '';
var reps = '';
var isToFailure = false;
setNumber = setList.indexOf(set) + 1;
weight = set['weight'].toString();
reps = set['reps'].toString();
isToFailure = set['isToFailure'];
if (isRowsGeneratedForPreviousExercises == false)
_generateDataTableRowsForCompletedExercises(
setNumber,
weight,
reps,
isToFailure,
);
isRowsGeneratedForPreviousExercises = true;
completedExercisesWidgetsList
.add(_completedExercisesDataTableWidget(exerciseName));
//for loop ends
///Return list of widgets - one widget for each completed exercise for the current workout
return Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(
dragDevices:
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
,
),
child: ListView(
shrinkWrap: true,
controller: _controller,
physics: const AlwaysScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
children: completedExercisesWidgetsList,
),
),
),
],
);
return const Text("There was a problem loading content.");
,
);
然后简单地从数据中生成 DataTable 行:
void _generateDataTableRowsForCompletedExercises(
setNumber, weight, reps, isToFailure)
dataRowsForCompletedExercises.add(
DataRow(cells: [
DataCell(Text(setNumber.toString())),
DataCell(Text(weight)),
DataCell(Text(reps)),
DataCell(
(isToFailure == true) ? const Icon(Icons.check) : const Icon(null)),
]),
);
【讨论】:
【参考方案2】:我相信你的问题是你在哪里使用'then'
试试这段代码,看看打印输出
var test = await FirebaseFirestore.instance
.collection('users')
.doc(currentUser!.uid)
.collection("workouts")
.doc(workoutId)
.collection("exercises")
.get()
print(test);
【讨论】:
它给出了 '_JsonQuerySnapshot 的实例以上是关于无法从嵌套集合中检索数据的主要内容,如果未能解决你的问题,请参考以下文章
从嵌套在 Firestore 文档中的集合中获取数据的最佳方法是啥?