Author: Sui Xiaoxu

Have you ever thought of developing a similar QQ, wechat chat application from scratch? Or want to add chat to your app to make it easier for users to communicate and engage? Well, this article is for you. In this article, I will introduce how to quickly implement a chat application based on Flutter.

Application profile

The Application based on Flutter is still being improved and now supports the following features:

  • Login and logout
  • A single conversation
  • A group chat
  • Supports text messages, voice messages, and picture messages
  • Displays the number of unread messages
  • Displays session members
  • You can change the session name
  • Support offline message push
  • Complain to report bad information
  • Example Add a user to the blacklist

Page screenshots

Development environment setup

Step 1: Install and setup the Flutter environment directly view the Flutter documentation. Step 2: Log in to the LeanCloud console and create the LeanCloud application.

  • On the Console, choose Applications > Settings > Domain Name Binding to bind the API to access the domain name. You can skip this step if you don’t have a domain name. LeanCloud also offers free domain names for short periods of time. Or sign up for LeanCloud International, which does not require a domain name.
  • On the Console > Application > Settings > Application Keys page, record the AppID, AppKey, and server address. The server address is the REST API server address. If no domain name is bound, a free shared domain name can be obtained at the same location on the console.

APP initialization Settings

In pubspec.yaml, add LeanCloud Flutter SDK to the dependency list:

Dependencies: leancloud_official_plugin: ^1.0.0-betaCopy the code

Then run flutter pub get to install the SDK.

Because the leanCloud_Official_Plugin is based on the Swift SDK and The Java Unified SDK, the latter two SDKS need to be installed so that the app can run on iOS and Android devices, respectively.

Install the Swift SDK through CocoaPods. This step is the same as installing other third-party libraries on iOS, by executing pod Update in the app’s iOS directory.

$CD ios/ $pod update # or $pod install --repo-updateCopy the code

To install the Java Unified SDK, open the project directory android/app/build. Gradle and add the following dependencies. Update Gradle synchronously.

dependencies {
implementation 'cn. Leancloud: storage - android: 6.5.11'
implementation 'cn. Leancloud: realtime - android: 6.5.11'
implementation 'the IO. Reactivex. Rxjava2: rxandroid: 2.1.1'
}
Copy the code

Tips: Post to the LeanCloud community for help when you encounter any difficulty installing the SDK.

After the SDK is installed, initialize the iOS and Android platforms respectively.

The user’s system

Demo does not have a built-in user system. You can select the user name in the contact list to log in to the chat system. You only need to pass a unique identifier string to the LeanCloud IM server to represent a user, which corresponds to a unique Client and uniquely identifies itself within the application (clientId).

In their own projects, if there is already a separate user system is easy to maintain. Or use the user system provided by LeanStorage.

The session list

The session list displays the session that the current user participates in, the session name, the session member, and the last message of the session. You also need to show the number of unread messages.

The session list corresponds to the Conversation table, and the following two lines of code are required to query all sessions of the current user:

ConversationQuery query = client.conversationQuery();
await query.find();
Copy the code

Sort by update time of session:

query.orderByDescending('updatedAt');
Copy the code

To display the latest message from the session, add this line of code to the query:

// Let the query result be accompanied by an updated message
query.includeLastMessage = true;
Copy the code

This takes care of the back-end data for the session page. Let’s look at how to display the data.

A successful session query returns data in the Conversation type List format.

  • Conversation. name indicates the session name
  • Conversation. members are session members
  • Conversation. lastMessage is the latest message for the current session.

Processing of unread messages

If you want to run it on an Android device, you need to initialize the Java SDK with the following line of code to enable unread message count notification:

AVIMOptions.getGlobalOptions().setUnreadNotificationEnabled(true);
Copy the code

Swift SDK is supported by default and no additional Settings are required.

Can listen onUnreadMessageCountUpdated time for number of unread messages inform:

client.onUnreadMessageCountUpdated = ({
  Client client,
  Conversation conversation,
}) {
  / / conversation. The number of unread messages unreadMessageCount namely the conversation
};
Copy the code

Note to clear the number of unread messages in the following two places:

  • Click a dialog in the dialog list to enter the dialog page
  • When a user is chatting in a conversation page and receives a message in that conversation

Session Details page

Pull up to load more history messages

To query chat history, first look up the last 10 messages, then start with the earliest message on the first page and continue to pull messages:

List<Message> messages;
try {
// The first query succeeded
  messages = await conversation.queryMessage(
    limit: 10,); }catch (e) {
  print(e);
}

try {
  // The message returned must be in time-incremented order, that is, the earliest message must be the first
  Message oldMessage = messages.first;
  // Start with the earliest message on the first page and continue to pull the message
  List<Message> messages2 = await conversation.queryMessage(
    startTimestamp: oldMessage.sentTimestamp,
    startMessageID: oldMessage.id,
    startClosed: true,
    limit: 10,); }catch (e) {
  print(e);
}
Copy the code

Changing the session Name

The Conversation name is a default Conversation property in the session table. Updating the session name requires only executing:

await conversation.updateInfo(attributes: {
  'name': 'New Name'});Copy the code

Pictures, voice messages

LeanCloud INSTANT Messaging SDK provides the following default message types. Demo uses only text messages, image messages, and voice messages.

  • TextMessage TextMessage
  • ImageMessage ImageMessage
  • AudioMessage AudioMessage
  • VideoMessage VideoMessage
  • FileMessage plain file messages (.txt/.doc/.md etc.)
  • LocationMessage geographic LocationMessage

Note that the image and voice messages need to be saved as LCFile before sending messages by invoking the message sending interface.

Like sending audio messages. Step 1 Save the audio file as LCFile:

LCFile file = await LCFile.fromPath('message.wav', path);
await file.save();
Copy the code

Step 2, send a message again:

// Send a message
AudioMessage audioMessage = AudioMessage.from(
  binaryData: file.data,
  format: 'wav',);await this.widget.conversation.send(message: audioMessage);
Copy the code

Note also that iOS devices send picture messages. Note that the album and camera permissions are enabled. Voice messages require microphone permissions:

< key > NSMicrophoneUsageDescription < / key > < string > need to access the microphone recording function, if not, you will not be able to send voice messages in the process of chat. </string> <key>NSCameraUsageDescription</key> <string> The send picture function requires access to your camera. If not, you will not be able to send picture messages during a chat. < / string > < key > NSPhotoLibraryUsageDescription < / key > < string > sending pictures function need access to your photo album. If not, you won't be able to send photos from your album during a chat. </string>Copy the code

Offline push notifications

When users log off and receive messages, they often hope to have a push reminder. The easiest way to do this is to go to the LeanCloud Console and choose Messages > Im > Settings > Offline Push Settings.

{ "alert": "You have news."."badge": "Increment" }
Copy the code

This allows iOS devices to receive notifications when offline messages occur. Here the badge parameter is dedicated to iOS devices and is used to increase the number count on the application badge.

If you want to implement offline push on Android devices, add a step to access Android hybrid push.

Of course, in real projects, the notification of offline messages is often required to be more specific, such as the content or type of message to be included in the push. LeanCloud also offers several other ways to customize your offline push, so you can browse the documentation for yourself.

Note that iOS push must be correctly configured to configure APNs push certificate, and turn on Xcode push switch:

To enable push in Appdelegate. swift, set it like this:

import Flutter
import LeanCloud
import UserNotifications

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        do {
            LCApplication.logLevel = .all
            try LCApplication.default.set(
                 id: "Your APPID",
                               key: "Your APPKey",
                               serverURL: "Server address")
            GeneratedPluginRegistrant.register(with: self)
            /* register APNs to access token, like this: */
            UNUserNotificationCenter.current().getNotificationSettings { (settings) in
                switch settings.authorizationStatus {
                case .authorized:
                    DispatchQueue.main.async {
                        UIApplication.shared.registerForRemoteNotifications()
                    }
                case .notDetermined:
                    UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in
                        if granted {
                            DispatchQueue.main.async {
                                UIApplication.shared.registerForRemoteNotifications()
                            }
                        }
                    }
                default:
                    break
                }
                _ = LCApplication.default.currentInstallation
            }
            return super.application(application, didFinishLaunchingWithOptions: launchOptions)
        } catch {
            fatalError("\(error)")}}override func application(_ application: UIApplication.didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        /* set APNs deviceToken and Team ID. */
        LCApplication.default.currentInstallation.set(
            deviceToken: deviceToken,
            apnsTeamId: "Your TeamId")
        /* save to LeanCloud. */
        LCApplication.default.currentInstallation.save { (result) in
            switch result {
            case .success:
                break
            case .failure(error: let error):
                print(error)
            }
        }
    }
    override func application(_ application: UIApplication.didFailToRegisterForRemoteNotificationsWithError error: Error) {
        // If the registration push fails, you can check the error message
        print(error)
    }
}
Copy the code

Complaint report, blacklist

In the APP Store review process, because users are free to send messages, appropriate precautions are required for user-generated content.

The following two items are required:

  • A mechanism for users to flag objectionable content

The mechanism for users to mark bad information is the report function.

  • A mechanism for users to block abusive users

Users to prevent abuse of the user mechanism, the actual blacklist.

Implement reporting function

My solution is to press the pop-up report window in the message director.

Use the LeanCloud storage service and create a Report table to record the Report information:

// Save a report message
LCObject report = LCObject('Report');
report['clientID'] = Global.clientID;   / / person
report['messageID'] = messageID;   / / message ID
report['conversationID'] = this.widget.conversation.id;  / / the session ID
report['content'] = _selectedReportList.toString(); // Report the content
await report.save(); // Save the report information
Copy the code

Reports can be viewed at the console:

Implement blacklist function

My solution is to click the contact dialog box in the contact list to ask you whether to add the contact to the blacklist.

To implement the BlackList, create a BlackList table to save the BlackList list of each user and use the LeanCloud cloud function to mask messages. Under the Hook function _messageReceived (this Hook occurs after the message reaches the LeanCloud cloud), check whether the sender and recipient of this message are in the blacklist list first. If they are in the blacklist list, delete the recipients required to be blocked and return the new recipient list.

It is also easy to implement. Paste the following cloud function into the LeanCloud Console > Cloud Engine > Cloud Function online edit box.

steps

First click “Create function”, then select the _messageReceived type, paste the code below, and finally click “Deploy” button.

After the deployment is complete, the blacklist function is successfully implemented and all messages of blacklisted users are not received.

// Paste the following function in the LeanCloud console

AV.Cloud.define('_messageReceived'.async function(request) {
let fromPeer = request.params.fromPeer;
let toPeersNew = request.params.toPeers;

var query = new AV.Query('BlackList');
query.equalTo('blackedList', fromPeer);
query.containedIn('clientID', toPeersNew);
return query.find().then((results) = > {
    if (results.length > 0) {
        var clientID = results[0].get('clientID');
        var index = toPeersNew.indexOf(clientID);
        if (index > -1) {
            toPeersNew.splice(index, 1);
        }
        return {
            toPeers: toPeersNew
        }
    }
    return{}}); })Copy the code

APP Project Address

See Github-FlutterRealtimeDemo for the complete APP project code

APP Store download link

The document

  • LeanCloud Instant Messaging plugin link
  • LeanCloud Instant Messaging development documentation
  • Flutter document