A Comprehensive Tutorial on Developing In-App Chat Functionality using ZEGOCLOUD and Flutter.
Tags: flutter, dart, zegocloud, inappchat
Published: 2023-04-15 12:47:40

[ZEGOCLOUD](https://www.zegocloud.com/) is a powerful platform that permits app builders to create actual-time video and audio calling apps readily. With ZEGOCLOUD sort of tools and software improvement kits, developers can build applications for video conferencing, online learning, and stay streaming. ZEGOCLOUD SDK lets in builders to add actual-time chat capability to their apps, allowing users to speak in actual-time thru text, voice, and video. Integrating ZEGOCLOUD SDK with Flutter is easy and easy, allowing builders to build and launch their in-app chat functionality quickly.
![ZEGOCLOUD](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kaaeydn3lhaq02g35gea.png)
Utilizing the `ZEGOCLOUD Flutter SDK`, developers can without problems expand software packages that enable people to have interaction in real-time video and audio conversations, in addition to utilize stay streaming talents alongside chat capabilities. within this composition, we shall offer a detailed manual on building an [In-app Chat](https://www.zegocloud.com/product/in-app-chat) with the ZEGOCLOUD Flutter SDK.
![in-app chat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a5z627rlqglyjdfxa51v.png)
Earlier than developing `in App Chat utility` the use of ZEGOCLOUD Flutter [In-app Chat](https://www.zegocloud.com/product/in-app-chat) SDK, it's far important to collect an App identity and App sign from the ZEGOCLOUD Console. those identifiers are vital in your utility to hook up with the ZEGOCLOUD platform and make use of its audio and video streaming competencies.
here are the steps to attain an App identification and an App sign:

1.Go to the ZEGOCLOUD Console internet site [Console](https://console.zegocloud.com/account/signup)
2.Sign up for an account and input your non-public statistics.

![Signup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/prbkjs4b9os6enk2u6sh.png)

3.After growing an account, you'll be induced to create a assignment. click the "Create" button to create a new undertaking.

![Create project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ww5gq6pftkiwlu6pqq15.png)

4.Enter a call on your venture and pick the proper place in your challenge. Then click on the "Create" button.
![Name](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4pynpfexickghtzkl1lv.png)

![UiKit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/910q3x742xf3f0ilhj6e.png)
5.Once your challenge is created, you may be redirected to the task dashboard.
![dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/29exigdyc3l7xvecv166.png)
6.Now click on service control after which select in-app chat to allow it.

![service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sfpvvpry61eb0inaje2y.png)
7.You may see your `App id` and `App sign` displayed on the web page. Make a note of these values as you will want them later when configuring your app.

**Be aware:** The `App sign` is a secret fee that should not be shared with all people. preserve it safe and secure.

## Create the Flutter Application
Let's move directly to creating our Flutter application:

Use the command "flutter create flutter_inappchat" to build new  project.

Next, we need to install [zego_uikit_prebuilt_call](https://pub.dev/packages/zego_uikit_prebuilt_call)
`flutter pub add zego_uikit_prebuilt_call`
Launch the project using your `IDE`, and perform some initial adjustments to ensure that the project runs smoothly.
Begin by accessing `android/app/build.gradle` and making modifications to the below-listed values:

1. `compileSdkVersion 33`
2. `minSdkVersion 22`

.` targetSdkVersion 33`
![build.gradle](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6b72bvw68aeur7ii2i3.png)
It is necessary to specify the permissions that the application will require. This can be done by adding the permission declarations within the manifest tag in the `AndroidManifest.xml `file:

```
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <!-- only invitation -->
    <uses-permission android:name="android.permission.VIBRATE"/>
```

![Permission](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hg6l0jp5sl94lwqiel9o.png)
Add the following permissions add to your Info.plist file for iOS:

```
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) camera use</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) microphone use</string>
```
Now that we've completed the essential configurations, we can begin writing our Dart code. To begin, you may substitute the code within the lib/main/home.dart file with the code provided below:

```
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:zego_zimkit/services/services.dart';
import 'package:zegocloud/main/dashboard_screen.dart';
class MainScreen extends StatefulWidget {
  const MainScreen({Key? key}) : super(key: key);
  @override
  State<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
  final TextEditingController _userIdController = TextEditingController();
  final TextEditingController _userNameController = TextEditingController();

  void changeSystemNavigationAndStatusBarColor(
      {Color navigationBarColor = Colors.white,
        Color statusBarColor = Colors.transparent,
        Brightness? statusIconBrightness = Brightness.dark,
        Brightness? navigationIconBrightness = Brightness.dark}) =>
      SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
        systemNavigationBarColor: navigationBarColor, // navigation bar color
        statusBarColor: statusBarColor, // status bar color
        statusBarIconBrightness: statusIconBrightness,
        systemNavigationBarIconBrightness: navigationIconBrightness,
      ));

  @override
  void initState() {
    changeSystemNavigationAndStatusBarColor();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        margin: const EdgeInsets.symmetric(horizontal: 20),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ////UserName
            TextFormField(
                controller: _userNameController,
                cursorColor: const Color(0xff424242),
                decoration: InputDecoration(
                  enabledBorder: _commonBorder,
                  focusedBorder: _commonBorder,
                  border: _commonBorder,
                  filled: true,
                  hintText: 'User Name',
                  fillColor: const Color(0xFFF3F2F2),
                  contentPadding:
                  const EdgeInsets.symmetric(vertical: 17, horizontal: 15),
                )),
            const SizedBox(height: 15),
            ///User ID
            TextFormField(
                controller: _userIdController,
                cursorColor: const Color(0xff424242),
                decoration: InputDecoration(
                  enabledBorder: _commonBorder,
                  focusedBorder: _commonBorder,
                  border: _commonBorder,
                  filled: true,
                  hintText: 'User Id',
                  fillColor: const Color(0xFFF3F2F2),
                  contentPadding:
                  const EdgeInsets.symmetric(vertical: 17, horizontal: 15),
                )),
            const SizedBox(height: 15),
            _commonButton('Log in', () async {
await ZIMKit().connectUser(id: _userIdController.text,name: _userNameController.text);
              // await ZIMKit().connectUser(
              //     id: _userIdController.text, name: _userNameController.text);
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (_) =>
                          DashBoardScreen(userId: _userIdController.text)));
            }),
          ],
        ),
      ),
    );
  }

  _commonButton(String btnName, VoidCallback onTap) {
    return ElevatedButton(
        onPressed: onTap,
        style: ElevatedButton.styleFrom(
            backgroundColor: const Color(0xff0155FE),
            shape:
            RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
            padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 10)),
        child: Text(
          btnName,
          style: const TextStyle(color: Colors.white, fontSize: 18),
        ));
  }

  get _commonBorder => OutlineInputBorder(
    borderRadius: const BorderRadius.all(Radius.circular(12)),
    borderSide: BorderSide(
        color: const Color(0xff424242).withOpacity(0.4), width: 2),
  );
}
```
Now you may substitute the code within the `lib/main/dashboard_screen.dart `file with the code provided below:

```
import 'package:flutter/material.dart';
import 'package:zego_zimkit/compnents/compnents.dart';
import 'package:zego_zimkit/pages/pages.dart';
import 'package:zegocloud/main/ChatPopUpOptions.dart';
class DashBoardScreen extends StatefulWidget {
  final String userId;
  const DashBoardScreen({Key? key, required this.userId}) : super(key: key);
  @override
  State<DashBoardScreen> createState() => _DashBoardScreenState();
}

class _DashBoardScreenState extends State<DashBoardScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        backgroundColor: const Color(0xff0155FE),
        elevation: 0,
        title: const Text('Chat and Groups'),
        actions: const [ChatPopUpOptions()],  ///Implimentation in new file
      ),
      body: Column(
        children: [
          _upperSection(),
          _chatAndGroupsVisibleSection(),
        ],
      ),
    );
  }

  _upperSection() {
    return InkWell(
      onTap: () {

      },
      child: Container(
        width: MediaQuery.of(context).size.width,
        height: 60,
        alignment: Alignment.center,
        child: Text(
          'User Id: ${widget.userId}',
          style: const TextStyle(fontSize: 16),
        ),
      ),
    );
  }

  _chatAndGroupsVisibleSection() {
    return Expanded(child: ZIMKitConversationListView(
      onPressed: (context, conversation, defaultAction) {
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (_) => ZIMKitMessageListPage(
                    conversationID: conversation.id,
                    conversationType: conversation.type)));
      },
    ));
  }
}
```
Now you may substitute the code within the lib/main/ChatPopUpOptions.dart file with the code provided below:

```
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:zego_zimkit/zego_zimkit.dart';
class ChatPopUpOptions extends StatefulWidget {
  const ChatPopUpOptions({Key? key}) : super(key: key);

  @override
  State<ChatPopUpOptions> createState() => _ChatPopUpOptionsState();
}

class _ChatPopUpOptionsState extends State<ChatPopUpOptions> {
  @override
  Widget build(BuildContext context) {
    return PopupMenuButton(
      shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(15))),
      position: PopupMenuPosition.under,
      icon: const Icon(Icons.more_vert_rounded),
      itemBuilder: (context) {
        return [
          PopupMenuItem(
            value: 'New Chat',
            child: const ListTile(
              leading: Icon(CupertinoIcons.chat_bubble_2_fill),
              title: Text('Create New Chat', maxLines: 1,),
            ),
            onTap: (){
              ZIMKit().showDefaultNewPeerChatDialog(context);
            },
          ), PopupMenuItem(
            value: 'Create New Group',
            child: const ListTile(
              leading: Icon(CupertinoIcons.group_solid),
              title: Text('Create New Group', maxLines: 1,),
            ),
            onTap: (){
              ZIMKit().showDefaultNewGroupChatDialog(context);
            },
          ), PopupMenuItem(
            value: 'Join New Group',
            child: const ListTile(
              leading: Icon(Icons.group_add),
              title: Text('Join New Group', maxLines: 1,),
            ),
            onTap: (){
              ZIMKit().showDefaultJoinGroupDialog(context);
            },
          ),
        ];
      },
    );
  }
}
```
As soon as you've got configured the required settings correctly, you must be capable of start a **in-app chat** app using the provided code.
## conclusion
In short, we've obtained information on growing an in-app messaging software the use of the `ZEGOCLOUD Flutter SDK`. The system entailed acquiring an`AppID and AppSign` from the `ZEGOCLOUD Console`, granting us get admission to to its audio and video streaming competencies. in the end, we generated a Flutter software and integrated crucial dependencies. in the end, we executed the in-app messaging characteristic with Dart language by means of initializing the SDK, becoming a member of a digital area, and publishing or subscribing to a transmission. Adhering to these steps, you may manufacture your personal in-app messaging software program utilising the ZEGOCLOUD Flutter SDK.
[Sign up for 10,000 free mins](https://bit.ly/3UgdPv9)
[Find out more about ZEGOCLOUD ](https://bit.ly/3nRyoBR)