1. Introduction
Goals
In this codelab, you'll instrument an in-app messaging experiment for a multi-platform mobile restaurant recommendation app powered by Flutter and Cloud Firestore.
Once finished, you will be able to design and implement in-app messaging experiments to effectively increase user engagement for any iOS or Android app while writing a minimal amount of code.
What you'll learn
- How to use Firebase In-App Messaging (FIAM) in a Flutter app
- How to customize the appearance of your in-app messages
- How to design an in-app messaging experiment and implement it in your app
- How to interpret the results of an in-app messaging experiment
What would you like to learn from this codelab?
Firebase In-App Messaging
Firebase In-App Messaging (FIAM) helps you engage users who are actively using your app by sending them targeted and contextual messages that nudge them to complete key in-app actions - like beating a game level, buying an item, or subscribing to content.
Firebase A/B Testing
Powered by Google Optimize, Firebase A/B Testing (ABT) helps you optimize your app experience by making it easy to run, analyze, and scale product and marketing experiments. It gives you the power to test changes to your app's UI, features, or engagement campaigns to see if they actually move the needle on your key metrics (like revenue and retention) before you roll them out widely.
What you need
If you're not very familiar with Flutter or Firestore, first complete the Firebase for Flutter codelab:
You can run this codelab using any of the following devices:
- A physical device (Android or iOS) connected to your computer and set to developer mode.
- The iOS simulator. (Requires installing Xcode tools).
- The Android emulator. (Requires setup in Android Studio).
In addition to the above, you'll also need:
- A browser of your choice, such as Chrome.
- An IDE or text editor of your choice, such as Android Studio or VS Code configured with the Dart and Flutter plugins. VS Code is recommended for use with Flutter.
- The latest stable version of Flutter (or beta if you enjoy living on the edge).
- A Google account, like a Gmail account, for creating and managing your Firebase project.
- The codelab's sample code. See the next step for how to get the code.
2. Get set up
Get the code
Clone the GitHub repository from the command line:
git clone https://github.com/FirebaseExtended/codelab-friendlyeats-flutter.git friendlyeats-flutter
The sample code will be cloned into the friendlyeats-flutter
directory. From now on, make sure you run commands from this directory:
cd friendlyeats-flutter
Then change into the codelab directory and check out the fiam-abt
branch:
git checkout fiam-abt
This branch contains all the code necessary for this codelab, including a completed version in the done
folder. The other branches in this repository contain code for building the FriendlyEats app, as shown in the Multi-platform Firestore Flutter codelab. For the purposes of this codelab, we've removed the web integration in this branch.
Import the starter app
Open or import the codelab-fiam-abt
directory into your preferred IDE. This directory contains the starting code for the codelab which consists of a restaurant recommendation app. Through this codelab, you will instrument an in-app messaging experiment for this app's users.
Create a Firebase project
- In the Firebase console, click Add project, and then name the Firebase project FriendlyEats. Remember the project ID for your Firebase project (or click the Edit icon to set your preferred project ID).
- Make sure Google Analytics is enabled for the project, then click Continue.
- Click Create project.
Congratulations! You just created your first Firebase project. Now, you can click on the project name to enter the console.
Next, you walk through configuring and enabling the necessary services using the Firebase console.
Enable Anonymous Auth
Although authentication isn't the focus of this codelab, it's important to have some form of authentication in your app. You'll use Anonymous login—meaning that the user is silently signed in without being prompted.
To enable Anonymous login:
- In the Firebase console, locate Authentication in the left navigation bar.
- Click Authentication, and then click Get started and select the Sign-in method tab (or go directly to the Firebase console).
- Enable the Anonymous Sign-in Provider, and click Save.
Enabling Anonymous login allows the application to silently sign in your users when they access the app. To learn more, see the anonymous authentication documentation for Android and iOS.
Set up Cloud Firestore
The app uses Cloud Firestore to save and receive restaurant information and ratings.
Here's how to set up Cloud Firestore in your Firebase project:
- In the left-panel of the Firebase console, expand Build and then select Firestore database.
- Click Create database.
- Leave the Database ID set to
(default)
. - Select a location for your database, then click Next.
For a real app, you want to choose a location that's close to your users. - Click Start in test mode. Read the disclaimer about the security rules.
Later in this codelab, you'll add Security Rules to secure your data. Do not distribute or expose an app publicly without adding Security Rules for your database. - Click Create.
3. Mobile-specific Firebase configuration
Most of the code changes required to enable Firebase support are already checked into the project that you're working on. However, in order to add support for mobile platforms, you need to:
- Register the desired platform on the Firebase project
- Download the platform-specific configuration file, and add it to the code.
In the top-level directory of your Flutter app, there are subdirectories called ios
and android
. These directories hold the platform-specific configuration files for iOS and Android, respectively.
Configure iOS
In the Firebase console, select Project Settings in the top of the left navigation bar, and click the iOS button under Your apps in the General page.
You should see the following dialog:
- The important value to provide is the iOS bundle ID. You get the bundle ID by performing the next three steps.
- In the command-line tool, go to the top-level directory of your Flutter app.
- Run the command
open ios/Runner.xcworkspace
to open Xcode.
- In Xcode, click the top-level Runner in the left pane, to show the General tab in the right pane, as shown. Copy the Bundle Identifier value.
- Go back to the Firebase dialog, paste the copied Bundle Identifier into the iOS bundle ID field, and click Register App.
- Continuing in Firebase, follow the instructions to download the configuration file
GoogleService-Info.plist
. - Go back to Xcode. Notice that Runner has a subfolder also called Runner (shown in the preceding image).
- Drag the
GoogleService-Info.plist
file (that you just downloaded) into that Runner subfolder. - In the dialog that appears in Xcode, click Finish.
- Go back to the Firebase console. In the setup step, click Next, skip the remaining steps, and go back to the main page of the Firebase console.
You're done configuring your Flutter app for iOS!
Configure Android
- In the Firebase Console, select Project Settings in the top of the left navigation bar, and click the Android button under Your apps in the General page.
You'll should see the following dialog :
- The important value to provide is the Android package name. You get the package name when you perform the following two steps:
- In your Flutter app directory, open the file
android/app/src/main/AndroidManifest.xml
. - In the
manifest
element, find the string value of thepackage
attribute. This value is the Android package name (something likecom.yourcompany.yourproject
). Copy this value. - In the Firebase dialog, paste the copied package name into the Android package name field.
- You don't need the Debug signing certificate SHA-1 for this codelab. Leave this blank.
- Click Register App.
- Continuing in Firebase, follow the instructions to download the configuration file
google-services.json
. - Go to your Flutter app directory, and move the
google-services.json
file (that you just downloaded) into theandroid/app
directory. - Back in the Firebase console, skip the remaining steps, and go back to the main page of the Firebase console.
- All the Gradle configuration is already checked in. If your app is still running, then close and rebuild it, to allow gradle to install dependencies.
You're done configuring your Flutter app for Android!
4. Run your app locally
You're ready to actually start work on your app! First, run the app locally. You can now run the app in any platform that you configured (and for which you have a device and emulator available).
Discover which devices are available with the following command:
flutter devices
Depending on which devices are available, the output of the preceding command looks something like this:
Now, run the app locally with the following command:
flutter run
Now, you should see your copy of FriendlyEats, connected to your Firebase project.
The app automatically connects to your Firebase project and silently signs you in as an anonymous user.
5. Create and test your first message
Integrate Firebase In-App Messaging into your app
The In-App Messaging basic integration is totally codeless, all you need to do is add the dependency and you're ready to go! Add the following dependency to your pubspec.yaml
file
dependencies:
# ...
firebase_in_app_messaging: ^0.4.0
# ...
Compose a message in the Firebase Console
Now that you've added FIAM to your app, lets compose a message that will trigger when your app is first opened.
To compose your first message:
- In the Firebase console's Engage section, click In-App Messaging.
- Click Create your first campaign in the In-App Messaging pane.
Lets compose a basic Modal message to make sure the integration is working. Feel free to customize the message in any way you'd like – you can add images, buttons, or change colors.
Be sure to target the app you want to test with, depending on what integration path you're following you might have iOS, Android, or both.
We want to make sure to have the message trigger when the app opens, so the default scheduling configuration will work here.
Once the scheduling is done we can publish the message. Click "review" and you should see something like the following
View the message in your app
Now, uninstall and reinstall your app, and you should see the message you created display upon opening. Congrats, you just sent your first in-app message! In the next step, you will learn how to add an analytics event, in order to trigger an in-app message based on actions your users take in the app.
6. Integrate Firebase Analytics for advanced message triggering
Integrate Firebase Analytics into your app
In order to understand how users are interacting with our app, and trigger an in-app message based on their actions, we will now add an Analytics event for when a user clicks on a restaurant.
- Add the Firebase Analytics dependency to Flutter in
pubspec.yaml
dependencies:
# ...
firebase_analytics: ^1.0.1
# ...
- Import analytics in
home_page.dart
import 'package:firebase_analytics/firebase_analytics.dart';
- Add an instance of Firebase Analytics to the HomePage class in
home_page.dart
class HomePage extends StatefulWidget {
static const route = '/';
static FirebaseAnalytics analytics = FirebaseAnalytics();
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
- Fire an analytics event when the user clicks on a restaurant card in
home_page.dart
onRestaurantPressed: (id) async {
await HomePage.analytics.logEvent(name: 'click_restaurant');
Navigator.pushNamed(context,
RestaurantPage.route,
arguments: RestaurantPageArguments(id: id));
})
Edit your message to trigger on the analytics event
Now that we have an event "click_restaurant" let's trigger our in-app message based on that rather than when the user opens the app.
In the Firebase Console go back to In-App Message and edit your existing campaign
Now change the scheduling section to trigger the message from the new event
From there we can publish our changes by clicking the "review" button
Test out your trigger in the app
At this point you should be able to run you app with
flutter run
And when you click a restaurant you should see your In-App Message
7. Create a FIAM+ABT Campaign
Start with a goal
Our Friendlyeats app is already looking great, but for it to be useful we need to have some reviews. These will be sourced from Friendlyeats users, so let's find some way to encourage users to leave reviews.
First let's define our conversion event
Since we want to see if users are reviewing restaurants lets add an analytics event to measure this behavior.
- Import Firebase Analytics just like before and add an instance of Analytics to RestaurantPage in
restaurant_page.dart
class RestaurantPage extends StatefulWidget {
static const route = '/restaurant';
static FirebaseAnalytics analytics = FirebaseAnalytics();
final String _restaurantId;
RestaurantPage({Key key, @required String restaurantId})
: _restaurantId = restaurantId,
super(key: key);
@override
_RestaurantPageState createState() =>
_RestaurantPageState(restaurantId: _restaurantId);
}
- Now lets trigger an event in
_onCreateReviewPressed
when we save a review inrestaurant_page.dart
if (newReview != null) {
// Log successful review
await RestaurantPage.analytics.logEvent(name: 'review_success');
// Save the review
return data.addReview(restaurantId: _restaurant.id, review: newReview);
}
Configure A/B Test in the Firebase Console
Now that we know how to create in-app messaging campaigns, it's time to consider what kind behavior we'd like to encourage in our app through these campaigns. For FriendlyEats, we'd like more people to leave reviews, which would make the app more useful! There's a few ways we could encourage this using in-app messages. One is through a simple in-app message that just tells the user they should give the restaurant a review to help improve the FriendlyEats app. Another way is to use an in-app message to offer some type of incentive for providing a review, like a coupon or discount code to a given restaurant.
Both approaches could increase how often users provide reviews for restaurants on FriendlyEats, and it seems like providing a coupon could have an even stronger impact in this case. But, how much more likely would providing this coupon make users to write a review? Is it worth the cost of the coupon in the first place? To determine this, we will run an in-app messaging experiment! We can use Firebase A/B Testing to randomly display one of our in-app messages to users, and measure the effect this has on user behavior, kind of like a clinical trial. Best of all, this can be done completely through the Firebase console, with no code needed!
To compose your first in-app messaging experiment:
- In the Firebase console's Engage section, click A/B Testing.
- Click Create experiment, and select that you want to experiment with In-App Messaging. This will bring you to the experiment composer shown below.
Give your experiment a name and an optional description.
- The next step is where you will compose the different in-app messages you will send to users in your experiment. The first in-app message we will compose is the "baseline", or the control of our experiment. We can make this our simple "please make a review" message:
- Now that we have a baseline, we will now compose a variant, the in-app message that offers users a coupon code to encourage them to leave a review. This isn't fully visible in the preview below, but the Message title is "Take a coupon, leave a review!", and the message body is "Next time you're at the Burrito Cafe, use coupon code FRIENDLYEATS-15 at checkout for 15% off your order. And remember to leave a review after!". This will hopefully inspire some users to check out the Burrito Cafe!
In the next step, we will target our app and set the Exposure. This is the percentage of eligible users (those satisfying the targeting/triggering conditions) who will see one of the messages in the experiment. We can just set this to 100% for this example, as we'd like all users to see either the baseline or our coupon variant. If you want to have a control group which is shown no in-app message at all, you can reduce this exposure percentage.
- Next, you will define some goals for the experiment. This is the outcome of the experiment we'd like to measure. We'll set this as the
review_success
analytics event we defined in the previous section, as we'd like to see the impact our different in-app messages have on users leaving restaurant reviews. - For scheduling, we'll let the campaign begin immediately, and set
click_restaurant
as the triggering condition, so that users see one of the two in-app messages when they click on a restaurant.
- Now, all that is left is to review our experiment, and hit Start experiment. Then we can sit back and wait for the data from our experiment to come in!
Check out the data collection in real time
Now that we've started our experiment, FriendlyEats users will randomly see one of the two in-app messages we composed when they click on a restaurant, either the baseline message or the variant message. This will divide our users into two groups, based on which message they saw. We can then look in the Firebase console (again under the A/B Testing section) to compare live analytics data from both groups. It will take some time for data to come in, as we need to wait for users to actually see the in-app messages and act accordingly. Here's what your results could look like after enough data:
In this case, the variant improved upon the baseline significantly, so we could choose to select Roll out variant, which would then roll out the in-app message with the coupon to all users.
8. Congratulations
Congratulations, you've successfully created and run your first in-app messaging experiment. Now you can run an experiment in your own app, and use the results to make your in-app messaging campaigns more effective.
What's next?
Check out some of these codelabs...
Further reading
We've just scratched the surface of what can be done with Firebase In-App Messaging and Firebase A/B Testing. Check these out if you'd like to learn more...
- Create Messaging Experiments with A/B Testing
- Create Remote Config Experiments with A/B Testing
- Explore Use Cases of Firebase In-App Messaging
- Customize your Firebase In-App Messaging messages