You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何通过文档ID判断Firestore文档是否存在?

问题

我的Firestore中有一个名为likes的集合,该集合以用户邮箱作为文档ID存储用户相关数据,每个用户文档下嵌套liked集合,用于存储该用户点赞过的帖子ID对应的文档。

为实现点赞状态UI展示,我编写了如下StreamBuilder代码:

StreamBuilder(
  stream: FirebaseFirestore.instance
      .collection("likes")
      .doc(FirebaseAuth
          .instance.currentUser!.email)
      .collection("liked")
      .doc(id)
      .snapshots(),
  builder: (context, snapshot) {
    bool liked = false;

    if (snapshot.hasData) {
      var col = FirebaseFirestore.instance
          .collection("likes");

      var doc = col.doc(FirebaseAuth
          .instance.currentUser!.email);

      var col2 = doc.collection("liked");

      var doc2 = col2.doc(id).get();

      if (doc2 == null) {
        liked = false;
      } else {
        liked = true;
      }
    }
    return Row(
      children: [
        // Text(snapshot.data.toString()),
        IconButton(
            onPressed: () {
              liked
                  ? FirebaseFirestore.instance
                      .collection("likes")
                      .doc(FirebaseAuth.instance
                          .currentUser!.email)
                      .delete()
                  : FirebaseFirestore.instance
                      .collection("likes")
                      .doc(FirebaseAuth.instance
                          .currentUser!.email)
                      .collection("liked")
                      .add({"like": true});
            },
            icon: GradientIcon(
              height: height,
              width: width,
              icon: liked
                  ? CupertinoIcons.heart_fill
                  : CupertinoIcons.heart,
              gradient: const LinearGradient(
                  begin: Alignment.bottomLeft,
                  end: Alignment.topRight,
                  colors: [
                    Colors.deepPurple,
                    Colors.deepPurpleAccent
                  ]),
            )),
      ],
    );
  }),

原本想通过上述代码判断用户是否点赞特定帖子并更新UI,但因exist关键字已废弃,且快照始终存在数据,导致判断结果始终为true。请问如何通过文档ID正确判断Firestore文档是否存在?

解决方法

原代码核心问题

  1. 重复发起异步查询:在StreamBuilder的builder回调里又调用col2.doc(id).get(),这是异步操作无法同步判断结果,且完全没必要——StreamBuilder已经拿到了目标文档的快照。
  2. 文档存在性判断错误:应该用快照的exists属性判断,而非判断对象是否为null;
  3. 点赞/取消点赞逻辑错误:取消点赞时不应删除整个用户likes文档,而是删除liked集合下对应帖子ID的文档;点赞时需用帖子ID作为文档ID创建,而非add生成随机ID,否则无法通过文档ID精准匹配。

修正后的代码

StreamBuilder<DocumentSnapshot>(
  stream: FirebaseFirestore.instance
      .collection("likes")
      .doc(FirebaseAuth.instance.currentUser!.email)
      .collection("liked")
      .doc(id) // 用帖子ID作为文档ID,确保精准匹配
      .snapshots(),
  builder: (context, snapshot) {
    // 直接通过快照的exists属性判断文档是否存在
    bool liked = snapshot.hasData && snapshot.data!.exists;

    return Row(
      children: [
        IconButton(
          onPressed: () async {
            final targetDocRef = FirebaseFirestore.instance
                .collection("likes")
                .doc(FirebaseAuth.instance.currentUser!.email)
                .collection("liked")
                .doc(id);

            if (liked) {
              // 取消点赞:删除对应帖子ID的文档
              await targetDocRef.delete();
            } else {
              // 点赞:创建以帖子ID为ID的文档,内容仅需标记存在即可
              await targetDocRef.set({"like": true});
            }
          },
          icon: GradientIcon(
            height: height,
            width: width,
            icon: liked
                ? CupertinoIcons.heart_fill
                : CupertinoIcons.heart,
            gradient: const LinearGradient(
              begin: Alignment.bottomLeft,
              end: Alignment.topRight,
              colors: [Colors.deepPurple, Colors.deepPurpleAccent],
            ),
          ),
        ),
      ],
    );
  },
)

关键说明

  • 文档存在性判断:使用DocumentSnapshot的exists属性,这是Firestore官方推荐的判断文档是否存在的方式,不存在废弃问题;
  • 文档ID设计:点赞时必须用帖子ID作为文档ID(doc(id).set(...)),而非add生成随机ID,这样后续才能通过同一个doc(id)精准查询点赞状态;
  • 操作逻辑修正:取消点赞仅删除liked集合下对应帖子的文档,保留用户的likes根文档和其他点赞记录;
  • 自动UI更新:StreamBuilder会自动监听文档变化,点赞/取消点赞操作完成后,快照会实时更新,UI同步切换状态。

内容的提问来源于stack exchange,提问作者Mohammed Bekele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 14:52:21