Flutter - Using Firebase In-App Messaging

This tutorial shows you how to use Firebase In-App Messaging in Flutter, which allows you to send targeted, contextual messages to users.

If you have a mobile application, increasing user engagement is an important thing. One way to increase user engagement is by sending messages in the application, so that the users are encouraged to do something. It would be nice if the messages can be configured dynamically, so that you don't need to update the application for adding a new message. In addition, it would be better if the messages are contextual and targeted.

While you can implement your own service for that purpose, there's a ready to use service from Firebase called In-App Messaging. It enables you to send targeted, contextual messages inside the application. The messages can be configured from the Firebase Console, which means the developers do not need to do anything every time a message is created or updated. Another advantage of using In-App Messaging is the ease of integration. In this tutorial, I am going to show you how to use In-App Messaging in Flutter.

Integrate Firebase to Flutter Application

Like using other Firebase services, you need to integrate your Firebase account with your Flutter application. Basically, what you need to do is create a Firebase project and add application(s) to the Firebase project. Then, download and copy the config files to your Flutter project. You can read the details in our tutorial about integration with Firebase services in Flutter.

To use In-App Messaging in a Flutter application, you can use firebase_in_app_messaging package. Add the below dependency to your pubspec.yaml file.

  dependencies:
    firebase_in_app_messaging: ^0.5.0+3

You may get the following error when building the application.

  D8: Cannot fit requested classes in a single dex file (# methods: 117452 > 65536)
  com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
  The number of method references in a .dex file cannot exceed 64K.

That's because multidex is not enabled. To enable multidex, add the following line in the app/build.gradle

  android {
    defaultConfig {
        // other configs
  
        multiDexEnabled true // Add this line
    }
  }

Still on the same file, add multidex as a dependency

  dependencies {
    // Other dependencies

    implementation 'com.android.support:multidex:1.0.3' // Add this line
  }

If you have migrated to AndroidX, you should add the following instead.

  dependencies {
    // Other dependencies

    implementation 'androidx.multidex:multidex:2.0.1' // Add this line
  } 

Create a Campaign

To create a campaign, first you need to open the Firebase Console. Then, navigate to the In-App Messaging from the sidebar. If the account doesn't have any created campaign, you should see a button whose text is something like Create your first campaign.

Firebase In-App Messaging

Just click the button and you'll be redirected to a page where you can set up a campaign. In the first section, you need to set the style and content for the campaign. You can choose the message layout (card, modal, image only, top banner). Then, fill all the fields in the form which vary depending on the message layout. There are previews for the portrait and landscape modes which may help you to see the result. After all fields have been filled, you can click the Next button.

Firebase In-App Messaging - Style & Layout

In the next section, you need to enter the name and description for the campaign. Then, you need to determine the target for the campaign. You have to choose the app to be used. Optionally, you can add other criterias by choosing from the dropdown which allows you to filter eligible users based on parameters such as app version, languages, country/region, etc.

Firebase In-App Messaging - Target

After that, you have to determine when the campaign starts and ends. Another thing you need to set is the list of events that can trigger the campaign. Some of the events you can choose are on_foreground, app_launch, app_remove, fiam_dismiss, fiam_impression, screen_view, session_start. The form also allows you to set per-device limitation for the campaign.

Firebase In-App Messaging - Scheduling

The next section allows you to set the tag for the conversion events (optional). It can be used to count the impression or click where you can see the result in the Conversions page of the Firebase Console.

Firebase In-App Messaging - Conversion Events

The last section can be used to add some key-value pairs as the custom data (optional).

Firebase In-App Messaging - Additional Options

Lastly, you can review the campaign before publishing it. The campaign will be started once it has been published.

Receive In-App Messaging in Flutter Application

Once you have created a campaign and add the firebase_in_app_messaging in the dependency, the application can automatically receive the in-app messages. There is no additional setup necessary. Below is an example of a received message.

Flutter - Firebase In-App Messaging

However, if you want to manually trigger the application to fetch for the latest in-app messages, you can do it programatically. First, you need to import the plugin by adding the following at the top of your .dart file where you want to add the code for retrieving the messages manually.

  import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart'

Below is an example of how to trigger the application to retrieve the messages programmatically.

 
 FirebaseInAppMessaging.instance.triggerEvent("manual_trigger");

In certain conditions, you may want to temporarily disable the application from receiving in-app messages. For example, if the user is in the middle of finishing a transaction. The code below can be used to temporarily disable in-app messages. After the application is allowed to receive the messages, you need to re-enabled it.

  // Disable
  FirebaseInAppMessaging.instance.setMessagesSuppressed(true);

  // Re-enable
  FirebaseInAppMessaging.instance.setMessagesSuppressed(false);

Send Test Message

The Firebase In-App messaging only retrieves messages once per day in order to conserve power. During testing, you may want to retrieve the messages more than once per day. It can be done by sending a test message from the Firebase Console. In the campaign list, select the campaign you want to send, click the option icon, and choose Test on device. You're required to enter the installation ID. You can get the installation ID by looking for the following log

  I/FIAM.Headless: Starting InAppMessaging runtime with Installation ID YOUR_INSTALLATION_ID

However, if it doesn't appear, you need a workaround. The easiest workaround is by using the firebase_messaging plugin for Flutter. You need to add the following in the dependencies section pubspec.yaml file and run flutter pub get afterwards.

  dependencies:
    firebase_messaging: ^9.1.4

After that, you can import the plugin.

  import 'package:firebase_core/firebase_core.dart';
  import 'package:firebase_messaging/firebase_messaging.dart';

Then, add the following code to get the instance ID.

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

  void _getInstanceId() async {
    await Firebase.initializeApp();
    var token = await FirebaseMessaging.instance.getToken();
    print("Instance ID: " + token);
  }

The output should be a string in XXX:XXXXX format. The installation ID that you need to use is the part before the : (colon).

Full Code

  import 'package:firebase_core/firebase_core.dart';
  import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';
  import 'package:firebase_messaging/firebase_messaging.dart';
  import 'package:flutter/material.dart';
  
  void main() => runApp(MyApp());
  
  class MyApp extends StatelessWidget {
  
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Woolha.com Flutter Tutorial',
        home: FirebaseInAppMessagingExample(),
        debugShowCheckedModeBanner: false,
      );
    }
  }
  
  class FirebaseInAppMessagingExample extends StatefulWidget {
  
    @override
    _FirebaseInAppMessagingExampleState createState() => _FirebaseInAppMessagingExampleState();
  }
  
  class _FirebaseInAppMessagingExampleState extends State<FirebaseInAppMessagingExample> {
  
    @override
    void initState() {
      super.initState();
      _getInstanceId();
    }
  
    void _getInstanceId() async {
      await Firebase.initializeApp();
      var token = await FirebaseMessaging.instance.getToken();
      print("Instance ID: " + token);
    }
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Woolha.com Flutter Tutorial'),
        ),
        body: Center(
          child: OutlinedButton(
            child: const Text('Trigger In-App Messaging'),
            onPressed: () {
              FirebaseInAppMessaging.instance.triggerEvent("manual_trigger");
            },
          ),
        ),
      );
    }
  }

Summary

Firebase In-App Messaging allows you to send campaign messages for increasing user engagement. You can create the campaigns from the Firebase Console, then add the firebase_in_app_messaging plugin as a dependency. The plugin can automatically retrieve and display the messages without additional setup. If necessary, you can manually trigger the application to retrieve the messages. If necessary, you can also temporarily disable in-app messages.

You can also read about: