Talk to us
Talk to us

How to Build Flutter Chat App

How to Build Flutter Chat App

Flutter is a popular mobile app development framework, and building a chat app is a common use case for many developers. ZEGOCLOUD is a cloud-based communication platform that can be integrated into Flutter apps to enable real-time messaging, voice, and video calls. In this guide, we will explore how to build a Flutter chat app with the ZEGOCLOUD SDK, providing step-by-step instructions and tips for creating a seamless communication experience for your users.

Must-have features of a Good Chat App

Chat apps have become a primary mode of communication for both personal and professional purposes. To create a chat app that stands out in the crowded market, developers must focus on providing a seamless and enjoyable user experience. Here are some must-have features of a good chat app.

1. End-to-End Encryption

Privacy and security are critical concerns for chat app users. End-to-end encryption ensures that only the sender and the receiver can access the messages, providing a secure communication channel.

2. Real-Time Messaging

Users expect their messages to be delivered instantly. A chat app must have a real-time messaging feature that allows messages to be sent and received instantly.

3. Multimedia File Sharing

Users want to share multimedia files such as photos, videos, and documents. A good chat app should allow users to share multimedia files seamlessly.

4. Group Chats

Users often need to communicate with multiple people at the same time. A good chat app should allow users to create and participate in group chats.

Types of Chat Apps

There are various types of chat apps available in the market, each with its own unique features and functionality. In this section, we will discuss some of the popular types of chat apps.

1. Personal Chat Apps

Personal chat apps are designed to cater to individual communication needs, such as staying in touch with friends and family. They provide various features like emojis, stickers, multimedia file sharing, and voice and video calling, making communication more engaging and fun.

2. Business Chat Apps

Business chat apps are perfect for companies looking to streamline communication between employees, customers, and partners. With secure messaging, file sharing, team collaboration tools, and integration with other business applications, they are essential for efficient and effective communication.

3. Social Media Chat Apps

Social media chat apps have become an integral part of social media platforms like Facebook, Twitter, and Instagram. They allow users to communicate with their social media contacts through messaging, voice, and video calling, providing a convenient way to stay connected.

How to Build a Flutter Chat App with ZEGOCLOUD SDK

Building a chat app using Flutter, Google’s UI toolkit is an exciting and challenging project. It requires expertise in both front-end and back-end development. In this section, we’ll guide you through the essential steps of creating a Flutter chat app, from setting up the environment to implementing real-time chat functionality into your apps.

zegocloud adds chat feature


  • A ZEGOCLOUD developer account – Sign up
  • Create a project in the admin console for app credentials
  • Android/iOS device or emulator
  • Have flutter installed

Steps to Build Flutter Chat App with ZEGOCLOUD SDK

Craft your Flutter chat app effortlessly with the ZEGOCLOUD SDK by following these simple steps:

1. Create a project

Run the code below in your terminal to create your Flutter project if you already have Flutter installed on your computer.

flutter create [App_Name]
cd [App_Name]
flutter run

For more information on how to create a Flutter project, check Flutter Doc – Get started.

2. Import the SDK

a. Add zego_zim dependencies by accessing pubspec.yaml file.

    zego_zim: ^2.6.0

b. Execute ‘flutter pub get‘ command in the terminal after saving the added file.

c. To import the Web SDK while configuring a Web platform, add the following to your index.html file.

<script src="assets/packages/zego_zim/assets/index.js" type="application/javascript"></script>

3. Set permissions

No special permissions are required for iOS and Web. However, for Android, add permissions by editing the AndroidManifest.xml file located in the app/src/main directory.

<!-- The permissions required by SDK-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

4. Prevent code obfuscation

To avoid obfuscating the SDK public class names while building your Android app with Flutter, add the following to your project’s file.

-keep class **.zego.**{*;}

5. Import the header file

Include zego_zim.dart header file.

import 'package:zego_zim/zego_zim.dart';

6. Create a ZIM SDK instance

The initial step is to create a ZIM instance which corresponds to a client logging into the system. Suppose we have two clients A and B; to enable message exchange, both of them must create a ZIM SDK instance by calling the create method with their AppID and AppSign (not required for Web) obtained from the Prerequisites.

// Create a ZIM SDK instance.
//Create a ZIM SDK instance and pass in the AppID and AppSign.
ZIMAppConfig appConfig = ZIMAppConfig();
appConfig.appID = appID;
appConfig.appSign = appSign;


7. Configure ZIMEventHandler and listen to corresponding event callbacks.

Invoke the ZIMEventHandler method prior to a client user’s login, and implement the protocol methods to receive various event callbacks. Customize the event callbacks to receive notifications for SDK errors or message-related callbacks. Here’s an example code for handling connection status changes in the zim_event_handler_manager.dart file:

// The error code callback is triggered when the SDK returns error codes.

static void Function(ZIMError errorInfo)? onError;

// The token expiration callback is triggered when the token is about to expire, allowing for customization of the UI.

static void Function(int second)? onTokenWillExpire;

// The connection status callback is triggered when the connection status changes, enabling UI customization for this event.

static void Function(ZIMConnectionState state, ZIMConnectionEvent event, Map extendedData)? onConnectionStateChanged;

// The one-on-one message callback enables the receipt of message notifications after logging in.

static void Function(List<ZIMMessage> messageList, String fromUserID)? onReceivePeerMessage;

// The in-room message callback enables the receipt of message notifications after logging in and joining a room.

static void Function(List<ZIMMessage> messageList, String fromRoomID)? onReceiveRoomMessage;

// The new user join callback enables notifications when a new user joins the room after logging in and joining the same room.

static void Function(List<ZIMUserInfo> memberList, String roomID)? onRoomMemberJoined;

// The existing user leave callback enables notifications when a user leaves the room after logging in and joining the same room.

static void Function(List<ZIMUserInfo> memberList, String roomID)? onRoomMemberLeft;

8. Log in to the ZIM SDK

Begin by creating a ZIMUserInfo object containing the user’s information. Subsequently, both clients A and B can log in to the ZIM SDK by calling the login method.

// userID must be within 32 bytes, and can only contain letters, numbers, and the following special characters: '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '`', ';', ''', ',', '.', '<', '>', '/', '\'.
// userName must be within 64 bytes, no special characters limited.
ZIMUserInfo userInfo = ZIMUserInfo();
userInfo.userID = "userID"; //Fill in a String type value. 
userInfo.userName = "userName";//Fill in a String type value. 

  .then((value) {
      //This will be triggered when login is successful.
  .catchError((onError) {
      switch (onError.runtimeType) {
          //This will be triggered when the login fails.
          case PlatformException:
            log(onError.code); //Return the error code when login failed. 
            log(onError.message!);// Return the error indo when login failed.

9. Send messages

After successful login, client A can send messages to client B. The ZIM SDK currently supports the following message types shown in the image below:

message type

To send one-to-one messages, client A can call the sendMessage method with client B’s userID, message content, and message type ZIMConversationType. ZIMMessageSentResult callback notifies client A of successful message delivery. onMessageAttached callback provides a temporary ZIMMessage message before sending it, allowing implementation of business logic, such as obtaining message ID or displaying Loading UI effect while sending large content.

// To send a one-to-one message, set the [conversationType] to ZIMConversationType.peer.

ZIMTextMessage textMessage = ZIMTextMessage(message: "message");
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
// Set priority for the message
sendConfig.priority = ZIMMessagePriority.low;

ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "Title of the offline push";
pushConfig.content = "Content of the offline push";
pushConfig.extendedData = "Extended info of the offline push";
sendConfig.pushConfig = pushConfig;
ZIMMessageSendNotification notification = ZIMMessageSendNotification(onMessageAttached: (message){
//  The message not sent yet callback offers a temporary object that should match the created zimMessage object, useful for developing custom business logic like pre-displaying UI.


// Set message type.
ZIMConversationType type = ZIMConversationType.peer;

ZIM.getInstance()!.sendMessage(textMessage, toConversationID, type, sendConfig).then((value) => {
    // The callback on the results of message sending.
    // This callback can be used to catch the reason for message sending failure.

10. Receive messages

Upon logging in, client B will receive client A’s message via the onReceivePeerMessage callback configured in the ZIMEventHandler method.

ZIMEventHandler.onReceivePeerMessage = (messageList, fromUserID) {
    //Receives the messageList from fromUserID.
    //This callback will be triggered when receiving one-to-one messgaes.
    for (ZIMMessage message in messageList) {
        switch (message.type) {
            case ZIMMessageType.text:
                message as ZIMTextMessage;
            case ZIMMessageType.command:
                message as ZIMCommandMessage;
            case ZIMMessageType.image:
                message as ZIMImageMessage;
            case ZIMMessageType.file:
                message as ZIMFileMessage;

11. Log out

To log out a client, call the logout method.


12. Destroy the ZIM SDK instance

To destroy the ZIM SDK instance, call the destroy method.


For more information on advanced features and implementation, refer to the SDK documentation.

Run a Demo

The sample demo is a great way to explore ZEGOCLOUD’s ZIM SDK features.


Using the ZEGOCLOUD SDK to build a Flutter chat app simplifies the process and provides various features to enhance the app’s functionality. With this powerful tool, developers can easily add real-time updates, integrate voice and video calls, and ensure data security. Overall, the ZEGOCLOUD SDK is a valuable asset for building a robust and engaging chat app with Flutter.

Let’s Build APP Together

Start building with real-time video, voice & chat SDK for apps today!

Talk to us

Take your apps to the next level with our voice, video and chat APIs

Free Trial
  • 10,000 minutes for free
  • 4,000+ corporate clients
  • 3 Billion daily call minutes

Stay updated with us by signing up for our newsletter!

Don't miss out on important news and updates from ZEGOCLOUD!

* You may unsubscribe at any time using the unsubscribe link in the digest email. See our privacy policy for more information.