如何使用 Firestore 在 Flutter 中列出 favorites/bookmarks

How to list favorites/bookmarks in Flutter with Firestore

我有一个名为 Stuff 的 collection 标题。把它想象成 Twitter post.

{
    'stuffID': string
    'title': string
    'details': string
}

我有一个收藏夹 collection,表示谁喜欢哪个 post。一个用户可以收藏多个东西。

{
    'userID': string
    'stuffID': string
}

从第二个 collection 开始,我想获取当前用户最喜欢的所有 stuffID。我想用它们来获取第一个 collection 的其余信息。总之,我想列出用户最喜欢的所有内容。就像一个书签列表。

我想我必须使用两个 StreamBuilder 来实现这个。但是我无法让它工作。

这是我设法做到的:

  @override
  Widget build(BuildContext context) {
    final FirebaseAuth auth = FirebaseAuth.instance;
    final User? user = auth.currentUser;
    final userID = user!.uid;
    var resultStream = FirebaseFirestore.instance
        .collection('favorites')
        .where("userID", whereIn: [userID]).snapshots();

    return StreamBuilder<QuerySnapshot>(
        stream: resultStream,
        builder:
            (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot1) {
          if (snapshot1.hasError) {
            return Text('Something is wrong.');
          }

          if (snapshot1.connectionState == ConnectionState.waiting) {
            return Text("Loading");
          }
          snapshot1.data!.docs.map((DocumentSnapshot document1) {
            Map<String, dynamic> data1 =
                document1.data()! as Map<String, dynamic>;
            print(data1['stuffID']);
            Query _stuffStream = FirebaseFirestore.instance
                .collection('Stuffs')
                .where('stuffID', isEqualTo: data1['stuffID']);
            return StreamBuilder<QuerySnapshot>(
                stream: _stuffStream.snapshots(),
                builder: (BuildContext context,
                    AsyncSnapshot<QuerySnapshot> snapshot2) {
                  if (snapshot2.hasError) {
                    return Text('Something is wrong.');
                  }

                  if (snapshot2.connectionState == ConnectionState.waiting) {
                    return Text("Loading");
                  }

                  return ListView(
                    //showing the data
                    children:
                        snapshot2.data!.docs.map((DocumentSnapshot document) {
                      Map<String, dynamic> data =
                          document.data()! as Map<String, dynamic>;
                      String stuffID = data['stuffID'];
                      return ListTile(
                        title: Text(data['title']),
                        subtitle: Text(data['details']),
                      );
                    }).toList(),
                  );
                });
          });
          return const Center(child: CircularProgressIndicator());
        });
  }

当我使用此代码时,应用程序卡在加载屏幕上:

我尝试了两天,但我的所有尝试都失败了。你能帮忙吗?

我日复一日地进行越来越多的研究并找到了答案。我根据 here. 创建了代码 请注意,我在 Firebase 中更改了 collection 的设计。但它与其余代码完全无关。我只是想用更有效的方式来存储数据。

总而言之,我正在从收藏夹中获取 stuffID collection。并使用那个 stuffID 来获取东西。

@override
  Widget build(BuildContext context) {
    final FirebaseAuth auth = FirebaseAuth.instance;
    final User? user = auth.currentUser;
    final userID = user!.uid;

    return StreamBuilder<QuerySnapshot>(
      stream: FirebaseFirestore.instance
          .collection('favorites')
          .doc(userID)
          .collection(userID)
          .snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return const Text("Loadsing...");
        return Column(children: [
          ListView.builder(
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              itemCount: snapshot.data!.docs.length,
              itemBuilder: (context, index) {
                //return buildListItem(context, snapshot.data.documents[index]);
                return ListView(
                  scrollDirection: Axis.vertical,
                  shrinkWrap: true,
                  children: <Widget>[
                    StreamBuilder<QuerySnapshot>(
                        stream: FirebaseFirestore.instance
                            .collection('Stuffs')
                            .where('stuffID',
                                isEqualTo: snapshot.data!.docs[index]
                                    ['stuffID']) //seçilen döküman
                            .snapshots(),
                        builder: (context, snap) {
                          if (!snap.hasData) return const Text("Loading...");
                          return ListTile(
                            leading: CircleAvatar(
                              backgroundImage: NetworkImage(
                                  snap.data!.docs[index]['stuffImage']),
                            ),
                            title: Text(snap.data!.docs[index]['title']),
                            subtitle: Column(
                              children: <Widget>[
                                Text(snap.data!.docs[index]['details']),
                              ],
                            ),
                          );
                        }),
                  ],
                );
              }),
        ]);
      },
    );
  }