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

基于Flutter和Firebase的聊天应用如何实现用户拉黑功能?

Flutter + Firebase 聊天应用用户拉黑功能实现指南

拉黑功能的核心作用

  • 阻止被拉黑用户给你发送消息,或限制你给被拉黑用户发送消息(双向限制可按需配置)
  • 隐藏被拉黑用户的聊天记录,避免在会话列表中显示
  • 从联系人、推荐列表中移除被拉黑用户
  • 限制被拉黑用户查看你的个人资料、在线状态等隐私信息(若应用有相关功能)

具体实现步骤

1. Firebase 数据库结构设计

推荐使用Cloud Firestore(更适合复杂查询场景),给每个用户文档添加blockedUsers子集合存储被拉黑用户的UID:

  • 顶级集合:users,每个文档ID为用户的Firebase UID
    • 子集合:blockedUsers,每个文档ID为被拉黑用户的UID,可额外存储拉黑时间(可选)

如果使用实时数据库,结构示例如下:

{
  "users": {
    "current-user-uid": {
      "blockedUsers": {
        "target-user-uid": true
      }
    }
  }
}

2. 实现拉黑/取消拉黑操作

编写Flutter方法完成拉黑和取消拉黑的数据库操作:

// 拉黑指定用户
Future<void> blockUser(String currentUserId, String targetUserId) async {
  await FirebaseFirestore.instance
      .collection('users')
      .doc(currentUserId)
      .collection('blockedUsers')
      .doc(targetUserId)
      .set({'blockedAt': Timestamp.now()});
}

// 取消拉黑指定用户
Future<void> unblockUser(String currentUserId, String targetUserId) async {
  await FirebaseFirestore.instance
      .collection('users')
      .doc(currentUserId)
      .collection('blockedUsers')
      .doc(targetUserId)
      .delete();
}

在用户资料页或聊天界面添加按钮,点击时调用上述方法即可完成状态切换。

3. 检查拉黑状态

编写工具方法判断双方的拉黑关系:

// 检查当前用户是否拉黑了目标用户
Future<bool> isUserBlocked(String currentUserId, String targetUserId) async {
  final doc = await FirebaseFirestore.instance
      .collection('users')
      .doc(currentUserId)
      .collection('blockedUsers')
      .doc(targetUserId)
      .get();
  return doc.exists;
}

// 检查目标用户是否拉黑了当前用户(用于限制消息发送)
Future<bool> isCurrentUserBlocked(String currentUserId, String targetUserId) async {
  final doc = await FirebaseFirestore.instance
      .collection('users')
      .doc(targetUserId)
      .collection('blockedUsers')
      .doc(currentUserId)
      .get();
  return doc.exists;
}

4. 消息过滤逻辑

发送消息前校验

发送消息前先检查是否被对方拉黑,若被拉黑则禁止发送:

Future<void> sendMessage(String currentUserId, String targetUserId, String content) async {
  bool isBlockedByTarget = await isCurrentUserBlocked(currentUserId, targetUserId);
  if (isBlockedByTarget) {
    // 提示用户:对方已拉黑你,无法发送消息
    return;
  }
  // 生成唯一聊天房间ID(避免重复,将两个UID排序后拼接)
  String chatRoomId = [currentUserId, targetUserId]..sort().join('_');
  // 正常发送消息
  await FirebaseFirestore.instance
      .collection('chats')
      .doc(chatRoomId)
      .collection('messages')
      .add({
        'senderId': currentUserId,
        'receiverId': targetUserId,
        'content': content,
        'timestamp': Timestamp.now(),
      });
}

接收消息时过滤

监听聊天消息时,自动过滤掉来自被拉黑用户的内容:

Stream<QuerySnapshot> getFilteredChatMessages(String currentUserId, String targetUserId) {
  String chatRoomId = [currentUserId, targetUserId]..sort().join('_');
  return FirebaseFirestore.instance
      .collection('chats')
      .doc(chatRoomId)
      .collection('messages')
      .orderBy('timestamp', descending: true)
      .snapshots()
      .asyncMap((snapshot) async {
        bool hasBlockedTarget = await isUserBlocked(currentUserId, targetUserId);
        if (hasBlockedTarget) {
          // 过滤掉目标用户发送的所有消息
          return QuerySnapshot(
            docs: snapshot.docs.where((doc) => doc['senderId'] != targetUserId).toList(),
            query: snapshot.query,
          );
        }
        return snapshot;
      });
}

5. UI层适配

  • 联系人列表:查询联系人时排除blockedUsers中的UID,确保被拉黑用户不显示
  • 聊天界面:若对方被拉黑,隐藏输入框/禁用发送按钮,显示"已拉黑该用户"的提示
  • 用户资料页:根据拉黑状态切换按钮文字("拉黑"→"取消拉黑")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 04:52:53