android 如何从Flutter上的Firestore获得集合列表和集合下所有字段的列表?

g6ll5ycj  于 2022-11-20  发布在  Android
关注(0)|答案(1)|浏览(161)

我正在制作一个对话启动器应用程序,在这个应用程序中,用户可以选择不同类别的问题。用户登录后,应用程序的主页是这样的:

我目前列出所有这些类别的方法是将类别名称保存为文档ID,放在我称为“users”的集合下。然后我使用下面的代码片段获取所有这些文档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>中。我只是更改了一个全局索引变量,并再次设置了状态,以便根据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函数中,我有以下代码片段:

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)-〉问题关键字:问题字段
我想这样设置它:
用户-〉自动生成的ID -〉问题类别作为集合-〉问题关键字(标题为“问题”):question key(此处为实际问题)
这样,在每个集合下,我还可以列出与问题相关的字段,如它是浅、中还是深,我可以在以后添加。
我也想这样做,因为有时当我尝试使用提交问题页面时,我键入的问题没有被提交,我想这可能是因为我在文档ID下而不是在集合下提交问题。
总之,我的问题是如何将主页上的所有问题作为数据库中的集合列表列出?(1)单击类别名称时查看各个卡片上的问题,(2)向特定类别/集合提交新问题?如果我尝试做的事情不能以我希望的方式完成,有没有更有效方法?
我试着搜索如何在Flutter上的Firestore上获得集合列表,但我找到的所有答案都给了我一个关于如何在文档ID下获得List字段的解决方案。这就是为什么我问这个问题。

waxmsbnn

waxmsbnn1#

实际上,Flutter的Firebase SDK(我假设是Android/IOS的)没有任何预先构建的方法来获取firestore数据库中所有集合的List
但是,正如我所知,你可以通过Node.js编写的cloud函数来获得它们,请参考this和this
如果您愿意编写一个cloud函数来在您的flutter项目上实现这一点,那么这是可以的。
不过,我可以想到一个切实可行的解决方案,如果你感兴趣的话:

  • 创建另一个集合/文档,在其中列出您的firestore集合,对于您的precedent集合,我想您别无选择,只能手动添加它们,但如果您要在项目中为将来创建新集合,您可以实现检查集合名称是否存在的通用方法,并根据它来操作。

相关问题