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

Flutter+Firestore社交APP关注列表ID比对异常问题求解

问题根因

你代码的核心错误是使用了全局单一变量isFollowedByMe存储关注状态:

  • followingList.any(check)的逻辑是判断「当前打开的主页的粉丝列表中是否存在任意一个用户是你关注的」,只要列表里有1个你关注的用户,这个全局变量就会被设为true,所有列表项都会复用这个状态,自然所有用户都显示「取消关注」。
  • 你需要的是给每个列表项单独判断对应用户ID是否在你的关注列表里,而不是给整个列表只判断一次。

修复方案

第一步:优化查询逻辑,把我的关注列表存为Set提升查询效率

首先修改checkfollowers方法,不用全局的isFollowedByMe,而是把我的关注列表存为Set供列表项查询:

// 在ProfileState里新增变量
Set<String> myFollowingSet = {};

checkfollowers(BuildContext context, String? id) async {
    final auth = Provider.of<AuthState>(context, listen: false);
    myFollowingSet = {}; // 先清空旧数据

    try {
      final QuerySnapshot following = await _firestore
          .collection('following')
          .doc(auth.getCurrentUser.uid)
          .collection('userFollowing')
          .get();

      // 把我的关注列表存为Set,contains查询时间复杂度是O(1),比List的O(n)快很多
      for (var element in following.docs) {
        myFollowingSet.add(element.id);
      }
      notifyListeners();

      print(myFollowingSet);
    } catch (err) {
      print(err.toString() + 'this error is coming from profileState');
    }
}

第二步:修改列表项的状态判断逻辑

渲染每个用户项的时候,单独判断当前用户的ID是否在myFollowingSet里,不要用全局的isFollowedByMe:

userComponent(UserModel? model, BuildContext context) {
    final profileState = Provider.of<ProfileState>(context);
    final auth = Provider.of<AuthState>(context);
    // 新增:单独判断当前项的用户是否被我关注
    bool isCurrentUserFollowed = profileState.myFollowingSet.contains(model?.userId);

    return Container(
      margin: EdgeInsets.symmetric(horizontal: 10),
      padding: EdgeInsets.only(top: 10, bottom: 10),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          GestureDetector(
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) =>
                      ProfilePage(profileId: '${model?.userId}'),
                ),
              );
            },
            child: Row(
              children: [
                Container(
                  width: 60,
                  height: 60,
                  child: CircleAvatar(
                    radius: 50,
                    backgroundImage: NetworkImage('${model?.profilePic}'),
                  ),
                ),
                SizedBox(width: 10),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text('${model?.userName}',
                        style: TextStyle(
                            color: Colors.black, fontWeight: FontWeight.w500)),
                    SizedBox(
                      height: 5,
                    ),
                    Text(
                      '${model?.displayName}',
                      style: TextStyle(
                        color: Colors.grey[500],
                      ),
                    ),
                  ],
                )
              ],
            ),
          ),
          auth.getCurrentUser.uid == model?.userId
              ? Container()
              : GestureDetector(
                  onTap: () {
                    if (auth.getCurrentUser.uid == model?.userId) {
                      print('you can not follow your self');
                    } else if (isCurrentUserFollowed) {
                      // 取消关注后要把ID从Set里移除
                      profileState.myFollowingSet.remove(model?.userId);
                      profileState.handleUnFollow(context, model?.userId);
                      profileState.notifyListeners();
                    } else {
                      // 关注后要把ID加到Set里
                      profileState.myFollowingSet.add(model?.userId);
                      profileState.handleFollow(context, model?.userId);
                      profileState.notifyListeners();
                    }
                  },
                  child: AnimatedContainer(
                    height: 35,
                    width: 110,
                    duration: Duration(milliseconds: 300),
                    decoration: BoxDecoration(
                      color: isCurrentUserFollowed
                          ? AppColors.white
                          : AppColors.pinkaccent,
                      borderRadius: BorderRadius.circular(5),
                      border: Border.all(
                        color: Colors.grey.shade700,
                      ),
                    ),
                    child: Center(
                      child: Text(
                        isCurrentUserFollowed
                            ? 'UnFollow'
                            : 'Follow',
                        style: TextStyle(
                            color: isCurrentUserFollowed
                                ? Colors.black
                                : Colors.white),
                      ),
                    ),
                  ),
                )
        ],
      ),
    );
}

额外优化建议

  • 可以把myFollowingSet做本地缓存,不用每次进入粉丝列表都重新查询,只有关注/取消操作的时候更新缓存即可,减少数据库请求。
  • 如果粉丝列表数据量很大,用Stream实时监听我的关注列表变动,不需要手动刷新状态。

内容的提问来源于stack exchange,提问作者Jovane Mullings

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 03:15:03