在Flutter中查看Firestore后,在ListView构建器中刷新变量

ergxz8rk  于 2023-04-07  发布在  Flutter
关注(0)|答案(1)|浏览(93)

我在StreamBuilder中有一个Listview.builder()。在Listview builder中,我需要为Firestore中的每个项目获取数据,然后显示数据。但是因为查看数据库是一个Future操作,所以我需要await方法来等待数据并在之后显示。
这是我的代码,我在两个不同的类中创建。
头等舱:

StreamBuilder getFriends() {
  return StreamBuilder(
    stream: FirebaseFirestore.instance
        .collection("Users")
        .doc(AuthFunc().currentUser!.uid)
        .snapshots(),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.active) {
        log("${snapshot.data["Contact"]}");
        List list = snapshot.data["Contact"];
        friends = list;
        return ListviewSharedWidget(
            friends: friends, year: widget.year, idDay: widget.idDay);
      }
      return Container();
    },
  );
}

@override
Widget build(BuildContext context) {
  return SizedBox(
    height: 450,
    child: Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        SizedBox(
          height: 400,
          child: getFriends(),
        )
      ],
    ),
  );

二等舱:

@override
void initState() {
  year = widget.year;
  idDay = widget.idDay;
  friends = widget.friends;
  _getText();
  super.initState();
}

Future<void> _getText() async {
  await FirebaseFirestore.instance
      .collection("Users")
      .doc(AuthFunc().currentUser!.uid)
      .get()
      .then((value) {
    textEditingController.text = value["Answers"]["$year"]["$idDay"]["text"];
  });
}

@override
Widget build(BuildContext context) {
  return ListView.builder(
    itemCount: friends.length + 1,
    itemBuilder: (context, index) {
      String name = ""; // This variable causing problem
      TextEditingController controller = TextEditingController();
      FirebaseFirestore.instance
          .collection("Users")
          .doc(friends[index - 1])
          .get()
          .then(
        (value) {
          name = value["Name"]; // Here I update the variable
          controller.text = value["Answers"]["$year"]["$idDay"]["text"];
        },
      );
      return Center(
        child: Column(
          children: [
            TextFieldSharedWidget(
              controller: controller, // But this variable is well updated and the text 
                                      // is displayed
              name: name, // But when I use here, the variable is still empty
              currentUser: false,
            ),
            const SizedBox(
              height: 20,
            )
          ],
        ),
      );
    }
  );
}
mqkwyuun

mqkwyuun1#

如果每一项都要求您从数据库异步加载另一个文档,请考虑将该加载操作 Package 在FutureBuilder中。起初,它可能看起来有点奇怪,但请记住,FutureBuilder只是另一个小部件,就像任何其他小部件一样-因此即使您有一个列表,它通常也能正常工作。
比如说

@override
Widget build(BuildContext context) {
  return ListView.builder(
    itemCount: friends.length + 1,
    itemBuilder: (context, index) {
      return FutureBuilder(
        future: FirebaseFirestore.instance
          .collection("Users")
          .doc(friends[index - 1])
          .get(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Text("ERRor: ${snapshot.error}");
          }
          if (snapshot.hasData) {
            return Text(snapshot.data!.child("Name").value);
          }
          return CircularLoadingIndicator();
        },
      );
    }
  );
}
  • 注意:我没有测试上面的代码,所以请尝试自己修复语法和小问题。

避免加载所有这些单独文档的常用方法是在原始文档中复制所需的数据。例如,如果您不仅存储每个朋友的UID,还存储他们的姓名,则可以显示整个朋友列表,而无需加载所有单独朋友的文档。
在处理NoSQL数据库时,这种数据重复非常常见。如果您是这个领域的新手,我建议您查看NoSQL data modelingGet to know Cloud Firestore

相关问题