In-App Chatting with ZEGOCLOUD in Flutter

·

8 min read

Flutter Introduction

Flutter is an open-source Software Development kit by Google. You all are maybe confused about why to choose flutter when you have other platforms like Swift & Android. the reason is cross-platform feasibility, If you use swifts you can only run your app on IOS devices, If you choose Android you can only run your app on Android devices, but with Flutter, you can develop Web Applications, Mobile applications and even desktop Applications.

Also, the best part of flutter is you can create Web Applications and Mobile applications with a single code base, so you don't need to worry about maintaining different codebases for different devices (web/mobile).

Here I am developing a basic In-App Chatting feature with Flutter using the library ZEGOCLOUD. Let's talk about what is ZEGOCLOUD and Why use it.

ZEGOCLOUD

ZEGOCLOUD is a library/platform where you can find different products like Video/Audio calling, Live Streaming, In-App Chatting and much more.
By using this library you can instantly develop an app with these different features using just a chunk of code.
As compared to other libraries ZEGOCLOUD has a good price margin and also a free account to test your app feature.

Use cases

In today's world, in almost any industry or field, the In-App chatting feature is a must to be in Web/App Applications. Here are some most common use cases for In-App Chatting feature

Online shopping

In online shopping web/app In-App chatting is one of the core features, A customer service representative can answer queries from the customers and other employees with ease. A customer can get all details about any product & policies without even visiting any store.

Interactive live streaming

In today's world, interactivity is key. You want your audience to feel like you're talking to them, not just reading from a script. That's where In-App chatting comes in!

ZEGOCLOUD can help you integrate In-App chatting into platforms like YouTube Live Streaming, Slack and Discord. With ZEGOCLOUD, you can easily add live video, text chat and voice chat features to your platform.

Online consulting

In the age of Covid, the world has become restricted to their homes and a new era of online myth has begun. Today, patients can talk to doctors from different countries and get a consultation online. This ZEGOCLOUD library can be of great use in that scenario due to the "ultra-low latency" feature

Online Education

Online education is the future, In today's world if anyone wants to get an education from different universities he/she can simply get admission to any university if he/she is capable and can learn from anywhere. The in-App chatting feature can be really useful in this domain, as students can interact with professors with just one click.

List for ZEGOCLOUD In-App chatting platform Compatibility

  • Android

  • iOS

  • Windows

  • macOS

  • Web

ultra-low latency

The library provides ultra-low latency as low as 200ms and can deliver real time messages to users with this latency

Massive concurrency

The library can handle hundreds of millions of real messaging communication eg. a large-scale live communication event

Message deliverability

the priority feature is really helpful to deliver messages to other users on high priority.

Weak networks

we often encounter weak networks and due to this sometimes we miss important messages but with ZEGOCLOUD you can never miss messages on weak networking.

Here is a list of which ZEGOCLOUD In-App chatting features provide
One-on-one chat: We In-App chatting you can build a one-to-one chatting feature.

Group chat: In-App chatting you can build a group chatting feature.

Offline messages: ZEGOCLOUD provide online messaging functionality.

Offline notifications: When a user is online, you can send a notification to the user with help of ZEGOCLOUD In-App Chatting

Steps

Open the pubspec.yaml file, add the zego_zim dependencies as follows:

yaml
dependencies:
    zego_zim: ^2.5.0+1

After adding and saving the file, run the command flutter pub get in the terminal.

If you are configuring a Web platform, then you will need to in your index.html file, add the following to import the Web SDK.

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

Set permissions
For iOS, and Web: no special permissions need to be set.

For Android: Go to the app/src/main directory, in the AndroidManifest.xml file, and add the permissions.

<!-- 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" />

Prevent code obfuscation
When building your Android app with Flutter, to prevent obfuscation of the SDK public class names, in your project's proguard-rules.pro file, add the following:

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

Import the header file zego_zim.dart.

import 'package:zego_zim/zego_zim.dart';
// 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;

ZIM.create(appConfig);

You can get the AppId and AppSign from the dashboard->project

Before a client user's login, you will need to call the ZIMEventHandler method to implement a static Function object that contains various event callbacks of the ZIMEventHandler. And you can receive callback notifications when SDK errors occur or receive messages with the Function passed in.

implement the methods involved in the protocol to receive callbacks (you can customize the event callbacks, such as you can receive callback notifications when SDK errors occur or receiving message-related callback notifications).

The following is the sample code for changing the connection status changes in the zim_event_handler_manager.dart file:

Image description

Add event listeners to your code for real-time events capture

// The callback for receiving error codes. This callback will be triggered when SDK returns error codes. 
static void Function(ZIMError errorInfo)? onError;

// The callback for Token expires. This callback will be triggered when the Token is about to expire, and you can customize a UI for this event.  
static void Function(int second)? onTokenWillExpire;

// The callback for connection status changes. This callback will be triggered when the connection status changes, and you can customize a UI for this event.
static void Function(ZIMConnectionState state, ZIMConnectionEvent event, Map extendedData)? onConnectionStateChanged;

// The callback for receiving one-on-one messages. You can receive message notifications through this callback after login. 
static void Function(List<ZIMMessage> messageList, String fromUserID)? onReceivePeerMessage;

// The callback for receiving the in-room massages. You can receive in-room message notifications through this callback after login and joining a room.  
static void Function(List<ZIMMessage> messageList, String fromRoomID)? onReceiveRoomMessage;

// The callback for a new user joins the room. You can receive notifications when a new user joins the room through this callback after logging in and joining a room.
static void Function(List<ZIMUserInfo> memberList, String roomID)? onRoomMemberJoined;

// The callback for an existing user leaves the room. You can receive notifications when an existing user leaves the room through this callback after login and joining a room.
static void Function(List<ZIMUserInfo> memberList, String roomID)? onRoomMemberLeft;

Create a login logic in your code base for any client before join any room for chatting

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

ZIM
  .getInstance()
  .login(userInfo)
  .then((value) {
      //This will be triggered when login successful.
  })
  .catchError((onError) {
      switch (onError.runtimeType) {
          //This will be triggered when login failed.
          case PlatformException:
            log(onError.code); //Return the error code when login failed. 
            log(onError.message!);// Return the error indo when login failed.
            break;
          default:
      }
  });

To send one-to-one messages, for example, if client A wants to send a message to client B, then client A needs to call the sendPeerMessage method with client B's userID, message content, and other info. And client A can be notified whether the message is delivered successfully through the callback ZIMMessageSentResult.

// Send one-to-one messages.
ZIMTextMessage textMessage = ZIMTextMessage(message: "message");
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
ZIM
    .getInstance()
    .sendPeerMessage(textMessage, 'toUserID', sendConfig)
    .then((value) {
        //发This will be trigggered when messages sent successully.
    })
    .catchError((onError) {
        switch (onError.runtimeType) {
            case PlatformException:
            //This will be triggered when messages failed to be sent.
            break;
        default:
        }
    });

After client B logs in, he will receive client A's message through the callback onReceivePeerMessage which is already set in the ZIMEventHandler method.

When a message is received, you need to determine whether the message is a Text message or a Command message because these two message types are based on the basic message. You need to convert the basic message class to a concrete message type and then retrieve the message content from the Message field.

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;
                break;
            case ZIMMessageType.command:
                message as ZIMCommandMessage;
                break;
            case ZIMMessageType.image:
                message as ZIMImageMessage;
                break;
            case ZIMMessageType.file:
                message as ZIMFileMessage;
                break;
            default:
        }
    }
};

when you leave the chat you can call the logout method and destroy method to maintain space.
Log out
For a client to log out, call the logout method.

ZIM.getInstance().logout();

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

ZIM.getInstance().destroy();

Here is the documentation link from where you can follow the steps and create the custom feature Documentation

Here is a repo from where you can get a sample code Repository. If you found this repo useful don't forget to give it a stare.

Here is my YouTube channel from where you can find more content related to Software Engineering. Yar Coder