[英]How to get a list of collections and a list of all fields under a collection from Firestore on Flutter?
我正在制作一个对话启动器应用程序,在这个应用程序中,用户可以选择不同类别的问题。 这是用户登录后应用程序主页的样子:
我目前列出所有这些类别的方式是将类别名称保存为我称为“用户”的集合下的文档 ID。 然后我使用以下代码片段获取所有这些文档 ID/类别并将它们添加到List
中。 然后,我使用FutureBuilder
将此List<String>
转换为按钮List
。 下面的代码可以帮助阐明我在做什么:
第 1 步:获取所有文档 ID/类别名称:
List<String> questionCategories = [];
Future getCategories() async {
await FirebaseFirestore.instance
.collection('users')
.get()
.then((snapshot) => snapshot.docs.forEach(
(document) {
questionCategories.add(document.reference.id);
));
}
第 2 步:使用 questionCategories List<String>
创建按钮List
FutureBuilder(
future: getCategories(),
builder: (context, snapshot) {
return SizedBox(
height: MediaQuery.of(context).size.height - 250,
child: ListView.builder(
itemCount: questionCategories.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: GestureDetector(
onTap: //questionPageInit,
() {
print(collectionList);
Navigator.push(context,
MaterialPageRoute(builder: (context) {
//return ForgotPasswordPage();
return CategoryPage(
categoryName: questionCategories[index],
);
}));
},
child: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.deepPurple,
borderRadius: BorderRadius.circular(12),
),
child: Center(
child: Text(questionCategories[index],
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
))))),
);
},
),
);
},
),
选择类别后,问题卡上一次显示一个问题,在该卡下方,用户可以在下一个和上一个问题之间切换,然后洗牌。 这个页面看起来像这样:
我显示这些问题的方法是获取文档 ID 下所有字段的List
并将其添加到List<String>
。 当用户按下 shuffle、next 或 previous 时,我只需更改一个全局索引变量并再次设置 state 以根据哪个问题出现在List
中的特定索引处显示一个新问题。 下面的代码应该有助于阐明我在做什么:
void printAllQuestionsList(snapshot) {
Map<String, dynamic> data = snapshot.data() as Map<String, dynamic>;
for (String key in data.keys) {
print(key + data[key]!);
questionsList.add(data[key]);
}
}
Future getQuestionList() async {
if (questIndex > 1) {
return;
}
if (widget.categoryName == "ALL") {
await FirebaseFirestore.instance
.collection('users')
.get()
.then(((snapshot) => snapshot.docs.forEach((document) {
print(document.reference.id);
FirebaseFirestore.instance
.collection('users')
.doc(document.reference.id)
.get()
.then((snapshot) => {printAllQuestionsList(snapshot)});
})));
} else {
await FirebaseFirestore.instance
.collection('users')
.doc(widget.categoryName)
.get()
.then((snapshot) => {printQuestionList(snapshot)});
}
}
在小部件 Build function 中,我有这段代码:
FutureBuilder(
future: getQuestionList(),
builder: ((context, snapshot) {
// return TextField(
// decoration: InputDecoration(
// enabledBorder: OutlineInputBorder(
// borderSide: BorderSide(
// width: 5, //<-- SEE HERE
// color: Colors.greenAccent,
// ),
// borderRadius: BorderRadius.circular(50.0),
// ),
// ),
// );f
return Container(
margin: const EdgeInsets.all(15.0),
padding: const EdgeInsets.all(10.0),
width: 350,
height: 350,
decoration: BoxDecoration(
color: Colors.deepPurple[200],
borderRadius:
BorderRadius.all(Radius.circular(20))
// border: Border.all(color: Colors.blueAccent)
),
child: Align(
alignment: Alignment.center,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(
questionsList[index],
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 32,
),
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
),
),
));
}))
我在这个应用程序上有第二个页面,用于向现有或新Category
提交问题(如果他们输入我设置的正确密码)。
我使用以下代码片段来执行此操作:
Future addQuestion(String category, String question) async {
var usersRef = questionCollection.doc(category);
await FirebaseFirestore.instance
.collection('users')
.get()
.then((snapshot) => snapshot.docs.forEach(
(document) {
existingQuestionCategories.add(document.reference.id);
},
));
if (existingQuestionCategories.contains(category)) {
print("Document Exists! ");
questionCollection.doc(category).update({question: question});
} else {
// FieldPath pathfield = FieldPath.fromString(category);
//String category2 = pathfield.category;
print('No such document exists so now about to set document anew!');
print(category);
FirebaseFirestore.instance
.collection("users")
.doc(category)
.set({question: question});
}
}
这是我的 Firestore 数据库的组织方式
用户 -> 问题类别(文档 ID) -> 问题键:问题字段
这就是我想要设置的方式:
Users -> Autogenerated ID -> Question Categories as collections -> question key (titled “question”): question key (“实际问题在这里)
这样,在每个集合下,我还可以列出与问题相关的字段,例如它是轻度、中度还是深度,我可以稍后添加。
我也想这样做,因为有时当我尝试使用我的提交问题页面时,我输入的问题没有被提交,我认为这可能是因为我在文档 ID 下而不是在集合下提交问题.
总之,我的问题是如何从我的数据库中将我主页上的所有问题列为 collections 的列表? 此外,这将如何更改我编写的代码(1)在单击类别名称时查看各个卡片上的问题,以及(2)向特定类别/集合提交新问题? 如果我想做的事情不能按照我想要的方式完成,是否有更有效的方法来做到这一点?
我尝试在 Flutter 上搜索如何在 Firestore 上获取 collections 的列表,但我找到的所有答案都为我提供了一个关于如何获取文档 ID 下的字段List
的解决方案。 这就是我问这个问题的原因。
实际上,Flutter 的 Firebase SDK(我假设是 Android/IOS)没有任何预构建的方法来获取 firestore 数据库中所有 collections 的List
。
但是,据我所知,您可以使用云 function 来获取它们,例如使用Node.js
编写的示例,请参阅this和this 。
如果你愿意写一个云 function 来在你的 flutter 项目上实现这一点,那很好。
但是,如果您对此感兴趣,我可以考虑一个实用的解决方案:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.