Supercharge Your Flutter Chat App:Implement Chat Message Seen with Appwrite(Firebase Alternative) Episode [18]
Key Topics covered:
- Implement message read
- Show double green ticks
- Design message bubble
- Update message read to true
Description:
In this tutorial, we will learn how to implement chat message seen functionality in your Flutter app using Appwrite, an exceptional Firebase alternative. Are you looking to enhance your app's chat experience? Look no further! In this in-depth tutorial, we'll guide you through the step-by-step process of integrating real-time chat features with Appwrite, all while designing beautiful message bubbles and displaying accurate timestamps.
Update an extensions file.
- lib/core/extensions/extensions.dart
Add OnDateTime which extends DateTime
import 'package:intl/intl.dart';
extension OnDateTime on DateTime{
String get formatDateTime => DateFormat('dd MM yyyy hh:mm a').format(toLocal());
}
Code Snippet(MessageRepositoryProvider.dart):
- lib/core/providers/MessageRepositoryProvider.dart
We added MessageRepositoryProvider to have High Cohesion on our code. We created a new method updateMessageSeen()
import 'package:appwrite/appwrite.dart';
import 'package:chat_with_bisky/constant/strings.dart';
import 'package:chat_with_bisky/core/providers/DatabaseProvider.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
final messageRepositoryProvider = Provider((ref) => MessageRepositoryProvider(ref),);
class MessageRepositoryProvider{
Ref _ref;
Databases get _databases => _ref.read(databaseProvider);
MessageRepositoryProvider(this._ref);
Future<void> updateMessageSeen(String id) async{
try{
_databases.updateDocument(databaseId: Strings.databaseId,
collectionId: Strings.collectionMessagesId,
documentId: id,
data: {
'read':true
});
} catch(e){
print('updateMessageSeen $e');
}
}
}
Code Snippet(ChatAppwrite.dart):
- lib/model/ChatAppwrite.dart
Add below code in ChatAppwrite class
String? messageIdUpstream;
bool? delivered;
String? userId;
Code Snippet(MessageAppwrite.dart):
- lib/model/MessageAppwrite.dart
Add below code in MessageAppwrite class
bool? delivered;
Code Snippet(ChatRealm.dart):
- lib/model/db/ChatRealm.dart
Add below code in ChatRealm class
late String? messageIdUpstream;
late bool? delivered;
late String? userId;
Code Snippet(MessageRealm.dart):
- lib/model/db/MessageRealm.dart
Add below code in MessageRealm class
String? messageIdUpstream;
bool? delivered;
Don't forget to run the following command in your terminal to regenerate part Filesdart run realm generate
Code Snippet(RealmProvider.dart) modification:
Increase schema version since we are adding new schemas for chats and friends
- lib/core/providers/RealmProvider.dart
final config = Configuration.local([....,schemaVersion:3);
Code Snippet(MessageViewModel.dart):
- lib/pages/dashboard/chat/MessageViewModel.dart
Add messageId parameter in method createOrUpdateChatHead
Future<void> createOrUpdateChatHead(MessageAppwrite message, String key,
String friendUserId, String myUserId,String messageId) async {
......
// Update ChatAppwrite Object to have the following properties
ChatAppwrite chatAppwrite = ChatAppwrite(
delivered: false,
messageIdUpstream: messageId,
userId: state.myUserId,
.......
// Update MessageRealm Object to have the following properties
MessageRealm(id,
fileName: messageAppwrite.fileName,
messageIdUpstream: document.$id,
delivered: false
...........
)
}
// In if statement if results exists call this method
// In case statement case RealtimeNotifier.create: and case RealtimeNotifier.update: call below method after saving message into realm database
updateMessageRead(message);
Code Snippet(MessageViewModel.dart):
- lib/pages/dashboard/chat/MessageViewModel.dart
Add below method updateMessageRead to update read to true
updateMessageRead(MessageRealm message){
if(!myMessage(message) && message.read != true){
ref.read(messageRepositoryProvider).updateMessageSeen(message.messageIdUpstream?? "");
}
}
myMessage(MessageRealm message){
return message.senderUserId == state.myUserId;
}
Code Snippet(ChatListViewModel.dart):
- lib/pages/dashboard/chat/list/ChatListViewModel.dart
Add below code
ChatRealm(ObjectId(),
.............
delivered: chatAppwrite.delivered,
userId: chatAppwrite.userId,
messageIdUpstream: chatAppwrite.messageIdUpstream,
sendDate: DateTime.parse(document.$updatedAt),
)
Code Snippet(ChatMessageItem.dart):
- lib/widget/ChatMessageItem.dart
Add below code to update message read in Widget build(BuildContext context, WidgetRef ref){
final theme = Theme.of(context);
final style = theme.textTheme;
useEffect((){
if(!myMessage && message.read != true){
ref.read(messageRepositoryProvider).updateMessageSeen(message.messageIdUpstream?? "");
}
return null;
});
Code Snippet(ChatMessageItem.dart):
- lib/widget/ChatMessageItem.dart
Replace return buildChatLayout(message); with the code below. We are designing our message bubble
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(myMessage?0:16),
topLeft: Radius.circular(myMessage?16:0),
bottomLeft: const Radius.circular(16),
bottomRight: const Radius.circular(16),
),
color: myMessage ? Colors.grey.shade400: Colors.green.shade200
),
child: Column(
children: [
buildChatLayout(message),
Row(
mainAxisAlignment:
myMessage? MainAxisAlignment.end: MainAxisAlignment.start,
children: [
if(myMessage) const Spacer(),
Padding(padding: EdgeInsets.all(4),
child: Wrap(
alignment: WrapAlignment.end,
spacing: 8,
crossAxisAlignment: WrapCrossAlignment.end,
children: [
Text(message.sendDate!.formatDateTime,
style: style.labelSmall!.copyWith(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold
),),
if(myMessage)
Icon(message.read == true?
Icons.done_all_rounded : Icons.done_rounded,
size: 16,
color: message.read == true? Colors.green.shade800:Colors.white,)
],
),
)
],
)
],
)));
Conclusion:
We managed to implement message seen. We used useEffect from riverpod to update message read if not when building the view. In the next tutorial, we are going to implement Chat Message Delivered by showing 2 white double ticks. Don't forget to share and join our Discord Channel. May you please subscribe to our YouTube Channel.