Flutter和Firebae与单人聊天的简单实现(Firebase Realtime Database)

项目的实现效果

项目的实现效果如上图所示。简单介绍一下项目:假设用户A和用户B是朋友关系,用户A登陆之后朋友列表中有用户B,用户B登陆之后朋友列表中有用户A。点击朋友列表中的一个朋友,可以打开和朋友之间的聊天界面。用户A向用户B发送消息之后,用户B查看消息之后,用户A的聊天界面会显示为已读。

用户之间的聊天记录

上图是用户之间的聊天数据示例。Realtime Database内部是json数据结构,json数据结构是分层的。chats代表所有单人之间的聊天结合。图中的1代表id,两个用户之间的聊天的索引或者key,我们把用户的id和"_"连接形成聊天记录的id。示例代码,如下:

dart 复制代码
String generateChatId(String uid1, String uid2) {
  final uids = [uid1, uid2]..sort();
  return '${uids[0]}_${uids[1]}';
}

注意两个用户的uid需要排序,因为两个用户uid通过"_"连接组合可能有两种可能,如果用sort排序就能保证唯一性。 图中的2代表一条聊天信息的id。图中的3代表消息接受方的id,也就是朋友的id,属性值true代表朋友已经读过这条消息。其中还包括发送方用户的id:senderId,聊天的内容:text,发送消息的时间戳timestamp。

用户之间发送消息

dart 复制代码
Future<void> sendMessage(String myUid, String otherUid, String text) async {
  final chatId = generateChatId(myUid, otherUid);
  final ref = FirebaseDatabase.instance.ref('chats/$chatId/messages').push();

  await ref.set({
    'senderId': myUid,
    'text': text,
    'timestamp': ServerValue.timestamp,
    'readBy': {otherUid: false},
  });
}

示例代码如上所示,也就是向聊天集合中的messages添加一条聊天记录,key是自动生成的唯一的字符串。Realtime Database是低延迟,自动同步的数据库,只要本地数据库数据变动就会收到变化通知,如果网络连接正常,数据会同步到Realtime Database server,同时通知监听数据变化的client端,这在软件设计领域有点像订阅者通知模式,只不过是数据库的订阅通知。用户A向用户B发送消息,用户B收到消息的延迟大概是秒级单位。

标记消息已读

dart 复制代码
 String chatId =  generateChatId(
                  context.read<UserUid>().friend!.uid,
                  _auth.currentUser!.uid,
                );
                DatabaseReference ref = FirebaseDatabase.instance.ref('chats/$chatId/messages/${message.key}/readBy');
                final readBy = message.value['readBy'] as Map<dynamic, dynamic>?;

                if (readBy != null && readBy[_auth.currentUser!.uid] == false) {
                  await ref.update({
                    _auth.currentUser!.uid: true,
                  });
                }

只有readBy中属性名称和当前用户的id一样,并且它的值为false,才会在这条消息显示在屏幕的时候(用户查看)标记为已读。

消息的排序

ini 复制代码
 final messages = data.entries.toList()
          ..sort((a, b) {
            final tsA = a.value['timestamp'] ?? 0;
            final tsB = b.value['timestamp'] ?? 0;
            return tsA.compareTo(tsB);
          });

消息按照时间先后顺序排序,代码逻辑如上所示。

参考资料

项目已经上传到github上,地址是github.com/caiweihao/f... firebase.google.com/docs/databa...

相关推荐
2301_8227032012 分钟前
开源鸿蒙跨平台Flutter开发:幼儿疫苗全生命周期追踪系统:基于 Flutter 的免疫接种档案与状态机设计
算法·flutter·华为·开源·harmonyos·鸿蒙
2301_8227032040 分钟前
鸿蒙flutter三方库实战——教育与学习平台:Flutter Markdown
学习·算法·flutter·华为·harmonyos·鸿蒙
2301_822703203 小时前
开源鸿蒙跨平台Flutter开发:蛋白质序列特征提取:氨基酸组成与理化性质计算
flutter·华为·开源·harmonyos·鸿蒙
钛态4 小时前
Flutter 三方库 ethereum_addresses 的鸿蒙化适配指南 - 掌控区块链地址资产、精密校验治理实战、鸿蒙级 Web3 专家
flutter·harmonyos·鸿蒙·openharmony·ethereum_addresses
提子拌饭1334 小时前
开源鸿蒙跨平台Flutter开发:中小学百米跑信息记录表:基于 Flutter 的高精计时与运动学曲线引擎
flutter·华为·开源·harmonyos
SY.ZHOU4 小时前
移动端架构体系(四):View层的组织与调用方案
flutter·ios·架构·系统架构·安卓
2301_822703204 小时前
光影进度条:鸿蒙Flutter实现动态光影效果的进度条
算法·flutter·华为·信息可视化·开源·harmonyos
独特的螺狮粉5 小时前
城市空气质量简易指数查询卡片:鸿蒙Flutter框架 实现的空气质量查询应用
开发语言·flutter·华为·架构·harmonyos
李李李勃谦6 小时前
Flutter 框架跨平台鸿蒙开发 - 鲜花礼品配送
flutter·华为·harmonyos
牛马1116 小时前
Flutter BoxDecoration
前端·javascript·flutter