In today’s fast-paced digital world, real-time communication has become essential for connecting people across various contexts. Whether it’s social networking, customer support, or team collaboration, incorporating chat functionality into your Flutter app can revolutionize user engagement.
Introducing CometChat, a robust SDK that effortlessly integrates smooth and seamless 1-on-1 chat experiences into Flutter applications. This powerful tool empowers developers with a comprehensive set of features designed to enhance the chat experience, from message exchange and reactions to blocking unwanted contacts.
With CometChat, Flutter developers can create captivating chat experiences that foster better connections and engagement among app users. Say goodbye to static interactions and welcome a dynamic and interactive environment, where users can communicate in real-time, making your app truly come alive.
Explore the possibilities of incorporating CometChat’s real-time chat SDK into your Flutter app with its user-friendly implementation and extensive feature set. It opens up a whole new realm of interaction and engagement, taking your app to the next level.
CometChat SDK offers a plethora of benefits for implementing chat functionality in Flutter, empowering developers to create exceptional user experiences:
Real-time Messaging: With CometChat, users can enjoy seamless real-time messaging capabilities, enabling instant and fluid communication between individuals. Stay connected and engaged with lightning-fast message delivery.
Easy Integration: The CometChat SDK streamlines the integration process, ensuring a hassle-free experience for developers. The straightforward implementation allows you to quickly add robust chat functionality to your Flutter apps, saving valuable development time and effort.
Customizable UI Components: Tailor the chat UI to perfection with CometChat’s extensive customization options. From color schemes to typography, you have full control over the appearance of the chat interface, ensuring a cohesive and branded user experience that seamlessly integrates with your app’s design.
Cross-Platform Compatibility: Reach a broader audience by leveraging CometChat’s cross-platform compatibility. The SDK seamlessly supports both iOS and Android platforms, making it an ideal choice for Flutter developers targeting multiple devices. Develop once and deploy effortlessly across various platforms, maximizing your app’s reach.
User Management: Simplify user authentication and management with CometChat’s comprehensive user management system. Handling the creation and administration of user accounts becomes effortless, allowing you to focus on the core functionalities of your app while ensuring secure and seamless user experiences.
Sending messages with the CometChat SDK is a breeze, thanks to its intuitive and straightforward implementation. With the powerful API at your disposal, you can effortlessly send messages between users in real-time, ensuring instant communication within your chat app.
The CometChat SDK simplifies the process of sending messages by providing a comprehensive set of methods and callbacks. These powerful tools enable you to handle message sending seamlessly and deliver a smooth chat experience to your users. Whether it’s a simple text message or a more complex media file, it allows you to transmit various types of messages effortlessly.
By leveraging the CometChat SDK’s methods, you can easily handle the sending process, including validating message content, encrypting data for security, and managing message delivery. The SDK’s callbacks provide real-time updates, allowing you to display sent messages instantly and provide visual feedback to users.
Let’s take a look at an example of sending a text message:
await CometChat.sendMessage(
TextMessage(
text: _text, // "Text Message"
tags: ['pinned'], // tags as List<String>
metadata: _metadata, // additional custom data as Map
receiverUid: _receiverUid, // uid of the receiver
type: CometChatMessageType.text,
receiverType: CometChatConversationType.user,
),
onError: (CometChatException e) {
log('Send message failed with exception: ${e.message}');
},
onSuccess: (BaseMessage message) {
log('Text message sent successfully: $message');
// update the UI to show the sent message
},
);
In the above code snippet, we use the `sendMessage()` method from the `CometChat` class to send a text message to a single user. You can customize the message content, tags, metadata, receiver UID, and other parameters according to your requirements. The `onError` and `onSuccess` callbacks handle the result of the message sending process.
Receiving messages through CometChat SDK is a seamless and efficient process that ensures users receive incoming messages instantly.
The SDK’s real-time updates feature keeps users connected by delivering messages as soon as they are sent.
Here are some key points to understand how receiving messages works:
By leveraging the CometChat SDK’s real-time updates and missed message retrieval capabilities, you can create a chat experience that keeps users engaged and connected, regardless of their online status or connectivity interruptions.
Let’s take a look at an example of receiving messages in real-time:
class MessagesPage extends StatefulWidget {
const MessagesPage({super.key});
@override
State<MessagesPage> createState() => _MessagesPageState();
}
class _MessagesPageState extends State<MessagesPage> with MessageListener {
@override
void initState() {
super.initState();
CometChat.addMessageListener(_listenerId, this); // An ID that uniquely identifies the listener
}
@override
void dispose() {
CometChat.removeMessageListener(_listenerId);
super.dispose();
}
@override
void onTextMessageReceived(TextMessage message) {
log('Text message received successfully: $message');
// update the UI to show the received message
}
}
In the above code snippet, we create a MessagesPage widget that extends StatefulWidget and implements the MessageListener interface. By adding a message listener using CometChat.addMessageListener(), your Flutter app will receive real-time updates whenever a new message is received. The onTextMessageReceived() callback handles the received text messages, allowing you to update the UI accordingly.
To retrieve missed or past messages, you can use the following example code:
MessagesRequest messageRequest = (MessagesRequestBuilder()
..limit = 30 // limits the messages to fetch
..uid = _receiverUid // uid of the conversation's receiver
..messageId = _lastMessageId // -1 for fetching latest messages
).build();
messageRequest.fetchPrevious(
onSuccess: (List<BaseMessage> baseMessages) {
for (final message in baseMessages) {
if(message is TextMessage) {
log('Text message received successfully: $message');
// save and manage a local list to show all the messages on the UI
}
}
},
onError: (CometChatException e) {
log('Message fetching failed with exception: ${e.message}');
},
);
In this example, we use the MessagesRequestBuilder to create a MessagesRequest object. By specifying the limit, UID of the receiver, and the message ID (use -1 for fetching the latest messages), you can retrieve the desired messages. The fetchPrevious() method fetches the messages, and the onSuccess callback handles the received messages, allowing you to update the UI or perform any necessary processing.
Modifying messages with the CometChat SDK is a powerful feature that enhances the user experience by providing the ability to edit sent messages in real-time.
This functionality ensures that users can easily correct errors or update information within a chat conversation, leading to more meaningful and accurate communication.
Here are key points to understand about modifying messages:
By incorporating the message modification feature of CometChat SDK into your Flutter app, you empower users with the flexibility to edit their messages in real-time. This capability not only improves the overall user experience but also ensures that conversations are accurate and error-free, fostering better communication between users.
Let’s take a look at an example of editing a message:
TextMessage updatedMessage = oldMessage..text = 'New Text';
await CometChat.editMessage(
updatedMessage,
onSuccess: (BaseMessage message) {
log('Message Edited successfully: $message');
// update the UI to reflect the change
},
onError: (CometChatException e) {
log('Edit Message failed with exception: ${e.message}');
},
);
*You will need the ‘oldMessage’ object with updated fields in order to edit the message. Therefore, it is recommended to save all messages properly at the time of receiving, as mentioned in the previous sections.
In the above code snippet, we create an updatedMessage object of the TextMessage class, where we assign the new text to the text property of the `oldMessage` object. The editMessage() method is then called, passing the updatedMessage object. The onSuccess callback is triggered when the message is edited successfully, allowing you to update the UI accordingly. In case of any errors, the onError callback handles the exception.
To receive real-time message edit events, you can implement the following code snippet:
class _MessagesPageState extends State<MessagesPage> with MessageListener {
// make sure CometChat.addMessageListener(_listenerId, this); is called inside initState()
@override
void onMessageEdited(BaseMessage message) { log('Edited message received successfully: $message');
// update your local list and refresh the UI
}
}
In this example, we include the onMessageEdited() callback in our listener widget. When a message is edited, the callback is triggered, providing the updated message object. You can then update your local list and refresh the UI to reflect the changes.
Deleting messages with the CometChat SDK is a valuable feature that gives users control over their conversations. With real-time events for message deletion, users can easily remove their own messages, and the deletion is synchronized across all devices and participants in the chat conversation.
This functionality ensures that users can maintain the privacy and integrity of their conversations by removing sensitive or outdated information as needed.
Here are key points to understand about deleting messages:
With the CometChat SDK’s real-time message deletion capability, users can confidently manage their conversations and maintain the privacy and accuracy of their chat content. This feature enhances the overall user experience by providing a robust and flexible tool for content management within the chat application.
Let’s take a look at an example of deleting a message:
await CometChat.deleteMessage(
message.id,
onSuccess: (BaseMessage message) {
log('Message Deleted successfully: $message');
// update the UI to reflect the change
},
onError: (CometChatException e) {
log('Delete Message failed with exception: ${e.message}');
},
);
In the above code snippet, the deleteMessage() method is used to delete a message. It takes the message.id of the message to be deleted. The onSuccess callback is triggered when the message is deleted successfully, allowing you to update the UI accordingly. In case of any errors, the onError callback handles the exception.
To receive real-time message delete events, you can implement the following code snippet:
class _MessagesPageState extends State<MessagesPage> with MessageListener {
// make sure CometChat.addMessageListener(_listenerId, this); is called inside initState()
@override
void onMessageDeleted(BaseMessage message) { log('Deleted message received successfully: $message');
// update your local list and refresh the UI
}}
In this example, we include the onMessageDeleted() callback in our listener widget. When a message is deleted, the callback is triggered, providing the deleted message object. You can then update your local list and refresh the UI to reflect the changes.
Also read: Choosing the Perfect Framework for Your App: A Comparison of React Native and Flutter
Delivery and reading receipts are essential features of the CometChat SDK that greatly enhance the chat experience for users.
By providing real-time updates on message receipts, the SDK offers valuable information about the delivery and read status of messages, ensuring users have visibility into the progress of their conversations.
Here are key points to understand about delivery and reading receipts:
By incorporating delivery and reading receipts, you provide users with valuable insights into the status of their messages. This feature fosters effective communication, improves user engagement, and ensures a more seamless and transparent chat experience overall.
Let’s take a look at an example of marking a message as delivered and read:
CometChat.markAsDelivered(
message,
onSuccess: (_){
log('Message marked as delivered successfully');
},
onError: (CometChatException e){
log('Mark as delivered failed with exception: ${e.message}');
},
);
CometChat.markAsRead(
message,
onSuccess: (_) {
log('Message marked as read successfully');
},
onError: (CometChatException e){
log('Mark as read failed with exception: ${e.message}');
},
);
In the above code snippet, the markAsDelivered() method is used to mark a message as delivered, and the markAsRead() method is used to mark a message as read. Both methods take the message object as a parameter. The onSuccess callback is triggered when the operation is successful, allowing you to update the UI accordingly. In case of any errors, the onError callback handles the exception.
To receive real-time message receipt events, you can implement the following code snippet:
class _MessagesPageState extends State<MessagesPage> with MessageListener {
// make sure CometChat.addMessageListener(_listenerId, this); is called inside initState()
@override
void onMessagesRead(MessageReceipt receipt) {
// update your local list and refresh the UI
}
@override
void onMessagesDelivered(MessageReceipt receipt) {
// update your local list and refresh the UI
}
}
In this example, we include the onMessagesRead() and onMessagesDelivered() callbacks in our listener widget. When a message is read or delivered, the respective callbacks are triggered, providing the message receipt object. You can then update your local list and refresh the UI to reflect the changes.
Responding to messages becomes effortless with the CometChat SDK’s ability to retrieve message thread history. This powerful feature allows users to access and view previous messages within a conversation, ensuring seamless continuity in their interactions.
Here are key points to understand about responding to messages:
By incorporating the message thread history feature, Flutter developers can provide users with a seamless and user-friendly interface for responding to messages. This capability ensures that conversations flow smoothly and that users can engage with past messages effortlessly.
Let’s take a look at an example of replying to a message:
await CometChat.sendMessage(
TextMessage(
text: _text, // "Text Message" receiverUid: _receiverUid, // uid of the receiver
type: CometChatMessageType.text, parentMessageId: _parentMessage.id // id of the message you want to reply to
receiverType: CometChatConversationType.user,
),
onError: (CometChatException e) {
log('Send message failed with exception: ${e.message}');
},
onSuccess: (BaseMessage message) {
log('Text message sent successfully: $message');
// update the UI to show the sent message
},
);
In the above code snippet, the sendMessage() method is used to send a reply message. The TextMessage class is used to create the message object, where you provide the text content, receiver UID, message type, parent message ID (the ID of the message you want to reply to), and receiver type. The onSuccess callback is triggered when the message is sent successfully, allowing you to update the UI accordingly. In case of any errors, the onError callback handles the exception.
To fetch all the replied messages for a particular thread, you can use the following code snippet:
MessagesRequest messageRequest = (MessagesRequestBuilder()
..limit = 30 // limits the messages to fetch
..uid = _receiverUid // uid of the conversation's receiver
..messageId = _lastMessageId // -1 for fetching latest messages ..parentMessageId: _parentMessage.id // id of the parent message
).build();
messageRequest.fetchPrevious(
onSuccess: (List<BaseMessage> baseMessages) {
for (final message in baseMessages) {
if(message is TextMessage) {
log('Text message received successfully: $message');
// save and manage a local list to show all the replied messages on the UI
}
}
},
onError: (CometChatException e) {
log('Message fetching failed with exception: ${e.message}');
},
);
In this example, we create a MessagesRequest object using the MessagesRequestBuilder and set the desired parameters such as the limit of messages to fetch, the UID of the conversation’s receiver, the message ID (use -1 for fetching the latest messages), and the parent message ID (the ID of the parent message). Then, we call the fetchPrevious() method on the messageRequest object to fetch the previous messages in the thread. The onSuccess callback provides a list of base messages, and you can iterate through them to access and handle the replied messages accordingly. In case of any errors, the onError callback handles the exception.
Also Read: Stepping Up Your Flutter Game: Migrating from Version 1.0 to 3.0
Reacting to messages is made engaging and interactive with the CometChat SDK’s support for message reactions. This feature enables users to express their emotions, provide quick feedback, or engage in fun interactions within a chat conversation.
Here are key points to understand about reacting to messages:
By incorporating message reactions, developers can create a more interactive and expressive chat experience for users. This feature enhances engagement, fosters a sense of community, and adds a touch of fun to conversations.
CometChat offers support for message reactions through the Extensions API. To utilize the Reactions extension, follow these steps:
Enable Reactions: Enable the Reaction feature from the Extensions tab on the CometChat dashboard. This step ensures that the necessary functionality is activated for your application.
React to Messages: Utilize the callExtension() method of the CometChat SDK to react to specific messages using the reaction API details. This API allows you to associate an emoji or predefined reaction with a particular message, enabling users to express their emotions or provide quick feedback.
await CometChat.callExtension(
'reactions',
'POST',
'/v1/react',
{'msgId': message.id, 'emoji': emoji},
onError: (CometChatException e) {
log('React to message failed with exception: ${e.message}');
},
onSuccess: (Map<String, dynamic> _) => log('Reaction added successfully'),
);
*Calling the callExtension() method with an emoji that is already added will remove the emoji from that message.
The code snippet demonstrates how to react to a specific message using the CometChat SDK’s callExtension() method. It makes a POST request to the Reactions extension API (/v1/react) with the message ID and the chosen emoji. If an error occurs during the reaction process, the onError callback is triggered, allowing you to handle the exception and display an appropriate message. On successful reaction, the onSuccess callback is triggered, indicating that the reaction was added successfully.
As users interact with messages and express their reactions, the message itself will automatically update to incorporate those reactions. To retrieve the specific details of these reactions, you can rely on the onMessageEdited() callback of your listener widget. The metadata accompanying each message contains all the relevant information pertaining to the reactions. Here is an example of a sample response containing reaction details:
"@injected": {
"extensions": {
"reactions": { "😊": {
"user3": {
"name": "User3"
}
},
"👍": {
"user2": {
"name": "User 2",
"avatar": "https://linkto/profile.jpg"
},
"user1": {
"name": "User 1",
"avatar": "https://linkto/profile.jpg"
}
}
}
}
}
Here, user1 is a user’s uid.
To extract reactions from metadata, you can use the following code:
class _MessagesPageState extends State<MessagesPage> with MessageListener {
// make sure CometChat.addMessageListener(_listenerId, this); is called inside initState()
@override
void onMessageEdited(BaseMessage message) {
log('Edited message received successfully: $message');
_reactions = getReactions(
message.metadata?['@injected']?['extensions'] ?? {},
);
// update the UI to reflect the change
}
List<Reaction> getReactions(Map<String, dynamic> extensions) {
final reactionsData = extensions['reactions'];
// if the type of 'reactions' key is not Map then return empty list
if (reactionsData is! Map<String, dynamic>) return [];
final reactions = reactionsData.entries.map<Reaction>((rectionEntry) {
final reactors = (rectionEntry.value as Map<String, dynamic>)
.entries
.map((reactorEntry) {
return Reactor(
id: reactorEntry.key,
name: reactorEntry.value['name'] ?? '',
profileUrl: reactorEntry.value?['avatar'] ?? '',
);
}).toList();
return Reaction(
reactors: reactors,
emoji: rectionEntry.key,
count: reactors.length,
);
}).toList();
return reactions;
}
}
class Reaction {
final int count;
final String emoji;
final List<Reactor> reactors;
const Reaction({
required this.count,
required this.emoji,
required this.reactors,
});
}
class Reactor {
final String id;
final String name;
final String profileUrl;
const Reactor({
required this.id,
required this.name,
this.profileUrl = '',
});
}
The code snippet provides an example implementation for handling received reactions in the onMessageEdited() callback. The getReactions() function extracts the reaction data from the message’s metadata. It iterates through the reaction entries and creates a list of Reaction objects, where each Reaction contains information such as the emoji, count of reactors, and a list of Reactor objects representing users who reacted. The Reactor class encapsulates details about a user, including their ID, name, and profile URL.
Also read: Building Robust Authentication and Seamless Navigation in Flutter Web with GoRoute.
User blocking and unblocking features provided by the CometChat SDK offer users the ability to manage their interactions within the chat app, ensuring a personalized and secure chat experience. By incorporating these features, users gain control over their conversations and can safeguard themselves from unwanted communication.
Here are key points to understand about user blocking and unblocking:
By integrating user blocking and unblocking features, Flutter app developers empower users to shape their chat experience. These features provide control, privacy, and protection, enabling individuals to engage in meaningful conversations with trusted contacts while mitigating unwanted communication.
To block or unblock users, you can use the blockUser() and unblockUser() methods provided by CometChat SDK. These methods allow you to block or unblock multiple users in a single call. Here’s an example:
CometChat.blockUser(
[_receiverUid],
onSuccess: (Map<String, dynamic> map) {
if (map[_receiverUid] == true) {
_isBlockedByMe = true;
// update the UI to reflect the change
},
onError: (CometChatException e) {
log('Block user failed with exception: ${e.message}');
},
);
CometChat.unblockUser(
[_receiverUid],
onSuccess: (Map<String, dynamic> map) {
if (map[_receiverUid] == true) {
_isBlockedByMe = false;
// update the UI to reflect the change
},
onError: (CometChatException e) {
log('Unblock user failed with exception: ${e.message}');
},
);
You can call the getUser() method before fetching all the messages when the messages page is opened to check if a particular user is blocked or not. Here’s an example:
await CometChat.getUser(
_receiverUid,
onError: (CometChatException e) {
log('Get user failed with exception: ${e.message}');
},
onSuccess: (User user) {
_isBlockedByMe = user?.blockedByMe ?? false;
_hasBlockedMe = user?.hasBlockedMe ?? false;
// update the UI accordingly
},
);
To retrieve a list of blocked users, you can use the BlockedUsersRequest and BlockedUsersRequestBuilder classes provided by CometChat. You can customize the request to filter users based on specific criteria. Here’s an example:
BlockedUsersRequest blockedUsersRequest = (BlockedUsersRequestBuilder()
..limit = 50
..searchKeyword = 'abc' // to filter users with a keyword
..direction = CometChatBlockedUsersDirection.directionBlockedByMe
).build();
blockedUsersRequest.fetchNext(
onSuccess: (List<User> users) {
log('Blocked users: $users');
},
onError: (CometChatException e) {
log('Fetching blocked user failed with exception: ${e.message}');
},
);
In the above example, CometChatBlockedUsersDirection.directionBlockedByMe ensures that the list of blocked users contains only the users blocked by the logged-in user. You can modify the direction parameter as per your requirement.
Also read: Exploring Group Chat and Role-Based Access with CometChat SDK
In conclusion, integrating 1-on-1 chat functionality into your Flutter app using CometChat SDK offers several advantages. The SDK’s real-time messaging capabilities, easy integration process, customizable UI components, and cross-platform compatibility make it a reliable choice for enhancing user engagement and communication.
With CometChat, you can seamlessly implement features such as sending and receiving messages, modifying and deleting messages, delivery and reading receipts, responding to messages, reacting to messages, and user blocking. These features enable users to enjoy a rich and interactive chat experience, leading to enhanced user satisfaction and app usage.
If you’re interested in incorporating CometChat into your Flutter app, you can explore our specialized Flutter development services. Our team can help you leverage the full potential of real-time messaging and chat functionalities. Contact us today to learn more!