In-App Messaging in Flutter with Freshchat

In-App Messaging in Flutter with Freshchat

Freshchat provides a live chat feature on Web, Mobile and social media platforms like Whatsapp, Facebook Messenger, Slack, Spotify etc. It helps in connecting users on different platforms, engage them by helping them interact with each other and hence develop business.

Freshchat has some outstanding features. With Freshchat, one can:

  • Send in-app messages.
  • Set up email campaigns
  • Set user segments and target messages based on specific business logic
  • Push Notification services
  • Multi-channel messaging and much more..

In this article, we are going to explore in-app messaging + push notification features of Freshchat, which is an important feature in almost every mobile apps nowadays.😀

Prerequisite Knowledge

This article assumes that the reader has basic working knowledge of Android + iOS development in Flutter along with basic knowledge of the Dart language.

Installation

In order to integrate Freshchat plugin in our project:

  1. Add flutter_freshchat dependency to the project's pubspec.yaml file:
dependencies:
  flutter_freshchat: ^1.4.0
  1. Install it through the command line using the following command:
$ flutter pub get
  1. Import the Freshchat package and use in your project through:
import 'package:flutter_freshchat/flutter_freshchat.dart';

Android Integration

To set up Firebase Cloud Messaging (FCM) in your app, please follow this link

  • To handle background messages, add the com.github.freshdesk:freshchat-android dependency in your app-level build.gradle file that is located at <app-name>/android/app/build.gradle:
dependencies {
        // your other dependency plugins
    implementation 'com.github.freshdesk:freshchat-android:3.3.0'
  }

To handle remote messages sent by Freshchat via FCM when app is in background mode, add:

dart
<service android:name=".FcmMessageService"
         android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

Create a class FcmMessageService which handles the remote message inside FreshchatMessagingService.kt file that is located at <app-name>/android/app/src/main/kotlin.

dart
package <your package's identifier>

import com.freshchat.consumer.sdk.Freshchat;
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class FcmMessageService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
       if (Freshchat.isFreshchatNotification(remoteMessage)) {
            Freshchat.handleFcmMessage(this, remoteMessage);
        }  
    }
}

For java, create aFreshchatMessagingService.java file located at <app-name>/android/app/src/main/java:

package <your package's identifier>;

import com.freshchat.consumer.sdk.Freshchat;
import com.google.firebase.messaging.RemoteMessage;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;

public class FcmMessageService extends FirebaseMessagingService {

    @Overridepublic void onNewToken(String token) {
        super.onNewToken(token);
    }

    @Overridepublic void onMessageReceived(final RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        if (Freshchat.isFreshchatNotification(remoteMessage)) {
            Freshchat.handleFcmMessage(this, remoteMessage);
        }
    }
}

Since Freshchat does not provide a default FileProvider, add the following to your AndroidManifest.xml file that is located at <app-name>/android/app/src/main/AndroidManifest.xml for secure sharing of files and to grant temporary access to the files that Freshchat requires:

<manifest>
    ...
    <application>
        ...
          <provider
             android:name="android.support.v4.content.FileProvider"
             android:authorities="com.example.demoapp.provider"
             android:exported="false"
             android:grantUriPermissions="true">
               <meta-data
                  android:name="android.support.FILE_PROVIDER_PATHS"
                  android:resource="@xml/freshchat_file_provider_paths" />
           </provider>
        ...
    </application>
</manifest>

For those who have migrated projects to androidX, replace line android:name="android.support.v4.content.FileProvider" with android:name="androidx.core.content.FileProvider"

  • To define the resource used by the FileProvider, add this to the strings.xml file that is located at <app-name>/android/app/src/main/res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="freshchat_file_provider_authority">com.example.demoapp.provider</string>
</resources>

iOS Integration

To allow your app to access Photos and Camera of a phone running iOS, it is mandatory to provide these additional access permissions. Add the following to theinfo.plist file located at <app-name>/ios/Runner/info.plist:

    <key>NSPhotoLibraryUsageDescription</key>
    <string>To Enable access to Photo Library</string>
    <key>NSCameraUsageDescription</key>
    <string>To take Images from Camera</string>

After adding this, the user will be prompted with a dialog box asking for an "Allow" and "Don't Allow" input.

This completes the installation and set up process for the Freshchat plugin.

We shall now see how to use the Freshchat API's and a few use cases.

Using Freshchat

First, initialise the Freshchat plugin for the app in main.dart with the code below:

import 'package:flutter_freshchat/flutter_freshchat.dart';

await FlutterFreshchat.init(
            appID: "your App ID here",
            appKey: "your App Key here",
            domain: "your domain here"
)

You can find the AppId, AppKey and domain here in the Freshchat dashboard.

Screenshot_2020-12-29_at_1.01.03_PM.jpg

Also, send the fcmToken to Freshchat and add this method to the place where you are fetching your Firebase's token.

 await FlutterFreshchat.setupPushNotifications(token: fcmToken)

iOS push Notification

To set up the push Notifications for iOS, upload p.12 file of your project, its password and bundleId of your project

Screenshot_2020-12-29_at_1.01.39_PM.png

Android Push Notification

To set up the push Notifications for Android, add the FCM Server key of your project which firebase provides, here:

Screenshot_2020-12-29_at_1.01.49_PM.png

Users and Conversations

  • Create/Register a user in Freshchat
//creating a new user
FreshchatUser user = FreshchatUser.initial();
user.email = "test.com";
user.firstName = "test";
user.lastName = "user";
user.phoneCountryCode = "+91";
user.phone = "0123456789";

await FlutterFreshchat.updateUserInfo(user: user);

// Custom properties can also be included
Map<String, String> customProperties = Map<String, String>();
customProperties["loggedIn"] = "true";
customProperties["companyName"] = "company";
customProperties["userCategory"] = "admin";

await FlutterFreshchat.updateUserInfo(user: user, customProperties: customProperties);
  • Show conversation opens the conversation screen. One can set the title for the chat screen and can reply to the conversation like shown in the attachment.
await FlutterFreshchat.showConversations(tags: const [], title: 'CHAT_SCREEN_TITLE');

Screenshot_2020-12-31_at_5.18.08_PM.png

  • To restore the chats, restoreID is required. Do note that restoreID returns a value only once a conversation is initiated. Which means that for the first time, restoreID will be null.
int restoreId = await FlutterFreshchat.identifyUser(externalID: 'UNIQUE_ID', restoreID: 'RESTORE_ID');

where, externalID is the one which (email/userId) you want to uniquely identify the user with. The above call returns the restoreID.

  • To get the unread message count
int unReadMessageCount = await FlutterFreshchat.getUnreadMsgCount();

Screenshot_2020-12-29_at_1.00.35_PM.jpg

Common Issues

These are the issues which you might face repeatedly while running Freshchat on an iOS app and you can waste a lot of time while trying resolving them.

  • If you face any issues while running the iOS app, run the following:
cd /ios
rm Podfile.lock
pod install --repo-update
flutter clean
  • Swift compiler errors which says: include of non-modular header inside framework module 'flutter_freshchat.FlutterFreshchatPlugin' Objective-c module errors

    To fix them,

    • Open your iOS folder in xcode.
    • Open the pods folder present on the left side, just below the Runner.
    • Click on the freshchatSDK folder inside the pods folder and click on the freshchatSDK.h file.
    • Press cmd+options+0 for the right side pane to find the target membership frameworks.
    • Select the flutter_freshchat framwork and also make it public (present on the right side).

    Now, again run the project and everything will work as expected!

By making the header file (.h) to be public, swift compiler can easily compile the code written in Objective C language.

Please Note: Manually set up the target of the freshchatSDK.h when you switch or rebuild the xcode project. It seems like there is still an open issue on automating this.

Few takeaways (Tips) 😀

When you encounter any errors/issues in the middle of using the package:

  • From my experience, it is better to first look into the open and closed issues of the package by visiting View/report issues link . This saves a lot of time in figuring out the solution and also helps one in taking the community's help for a particular package.
  • Don’t get overwhelmed by the installation procedures put up by multiple articles at once, simply follow one at a time

Happy chatting !!😄