Written by Mike Hughes
Firebase App Distribution is a service that allows you to distribute pre-release apps to testers. It’s like using Google Play for internal/alpha/beta releases, but with less setup, waiting and hoops to jump through. This makes it a good way to distribute early versions of you app for alpha testing before going through Google Play setup.
If you’d like to know more about everything that Firebase App Distribution can do, you should take a look at the official documentation.
There are three ways to get your apps into Firebase App Distribution:
- Firebase App Distribution of Android apps using the Gradle plugin with Codemagic is covered in this article.
- Firebase App Distribution of Android and iOS apps using the Command line Interface (CLI) with Codemagic is covered in another article here.
- Firebase App Distribution using fastlane locally is covered in yet another article here.
This article focuses on setting up the distribution of your Flutter Android apps to testers via Firebase App Distribution using the Gradle plugin in Codemagic.
Why use the Gradle method?
To be frank, the easier approach is to use the CLI method to distribute both Android and iOS builds of your Flutter app to Firebase App Distribution. So use this approach unless you need to use the Gradle plugin for other reasons. Some of the reasons to use the Gradle plugin (instead of the CLI) might be that:
- You only need to distribute to Android and are comfortable with Gradle.
- You already use Gradle to build different flavours of your app.
- You want to send your builds to Firebase App Distribution both from your local machine and Codemagic.
- Your existing build setup is already extensively using Gradle.
If you choose to use the Gradle plugin approach, this how it works:
- Install the Firebase App Distribution Gradle plugin into your Flutter Android project.
- Codemagic’a post-publish script uses the Gradle plugin setup within your Flutter project to distribute your app build to Firebase App Distribution.
- Firebase App Distribution then distributes your app automatically (if you have set this up).
Things to note:
- This allows only for Android builds of your Flutter app.
- It allows for only one build and no failed builds. Your app is not rebuilt, it is still only built once by Codemagic, so it uses very few Codemagic build minutes. Typically this is less than 1 minute and if your build fails, the app is not sent to Firebase App Distribution nor released to testers.
- The app gets to testers fast. Your app will appear in the Firebase App Distribution console immediately. There is no review, no long processing and it is ready for automatic distribution to testers. Typically, I find that testers are notified of the new release of the app within a minute of the Codemagic build finishing.
Set up a Firebase project and Firebase support for your Flutter project
To make sure that your app has Firebase support, you have to set it up yourself. This is actually the biggest hurdle of the whole project. There are two parts to that:
- Firebase project – a single Firebase project via the Firebase web console.
- Flutter project Firebase support – you set up Firebase support for the Android versions of your app in the Firebase web console and within your Flutter project.
You may want Firebase support for your project for other capabilities such as Firebase Analytics, Crashlytics or one of the other Firebase services. This is a one-time setup for all Firebase services, so it’s well worth your time.
I will not repeat these steps here as the official documentation is clear, easy to follow and, more importantly, maintained and up to date. So I’d recommend following the official guide “Add Firebase to your Flutter app”, which has instructions for both Android (and iOS). A couple of tips about some steps described there as you do this:
Step 2 (“Register Your App with Firebase”) - For Android you probably won’t need a SHA-1 Debug Signing Certificate at this stage, as only some Firebase services require it.
Step 4 (“Add FlutterFire Plugins”) You may want to add Firebase Analytics plugin as well while you are here. Check the latest versions of FlutterFire packages like flutter_analytics on pub.dev.
google-services.json
and it should thus be secured!If your project repository is public then anyone can look at this file in your repository and get your credentials. To secure this file in a Codemagic environment variable, exclude it from going into your repository via the .gitignore
file and encrypt it. If you need any help, take a look at this blog post, which covers how to secure your google-services.json
file in Codemagic environment variables and encrypt it.
Gradle plugin project setup
This is a one-time setup based on Firebase App Distribution Gradle plugin, Flutter and Firebase documentation. This guide will provide some more detail and hopefully help you skip common mistakes.
In your Flutter project you’ll have to update both of your build.gradle
files:
/android/build.gradle
- in the dependencies’ section within buildscript add thefirebase-appdistribution-gradle
line:
dependencies {
// ... your other dependencies
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-appdistribution-gradle:2.0.0'
}
/android/app/build.gradle
- add a new line after theapply
plugin (com.android.application
) for theappdistribution
plugin:
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.firebase.appdistribution'
Authenticate with Firebase using a service account
Before you can use the Firebase App Distribution Gradle plugin, you must first authenticate with your Firebase project. There are three ways to achieve this, but since we want to use Codemagic for CI/CD, you should choose the second option and use Firebase service account credentials.
Authenticating with a service account allows you to flexibly use the plugin with Codemagic. Firebase runs on top of the Google Cloud Platform, so we need to create a service account for our Firebase project in the Google Cloud Platform console. To do this:
Go to the Google Cloud Platform console and log in with the same account you use to log into the Firebase console.
Select your Firebase project. It should be listed there but if it is not, search for it by name:
From the menu, select IAM & admin/service accounts to see a list of the default service accounts already set up for your Firebase project.
Click on + CREATE SERVICE ACCOUNT and specify details for this new service account (like on the picture below) and then click CREATE.
Select the role of Firebase App Distribution Admin and click CONTINUE.
The next step is labeled as Grant user access to this service account (optional). Just click DONE here.
Click the + CREATE KEY button to create a JSON key like this. To confirm the action, click CREATE.
- This creates a private json key, so save the key file to a location accessible to your build environment.
yourappname-6e632def9ad4.json
.Temporarily make a copy of this json key file and put it in your Flutter project in the
/android
directory. We’ll be using this to test the setup later, although we don’t want this file to go into any public repositories, because it is a private key that allows full admin access to your Firebase project.Click DONE when finished and you should see your new service account appear in your list of service accounts.
Configure app distribution properties
In your /android/app/build.gradle
file configure app distribution by adding at least one firebaseAppDistribution
section. Add it in the Android section within buildTypes
. All the options are explained in the documentation, under step 3, Configure your distribution properties.
For example, if you have an app and you want a Flutter release build to be used by testers, you would use the following code:
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
firebaseAppDistribution{
serviceCredentialsFile="./yourappname-6e632def9ad4.json"
releaseNotesFile="../release-notes.txt"
testers="your-email-address@gmail.com"
}
}
}
Take special note of the following properties:
serviceCredentialsFile
- this is the private key json file we created previously for the service account. It should be located in the/android
directory of your project. If you placed it somewhere else in your project, then adjust the path relative to your/android
directory.releaseNotesFile
- this can be specified and will appear in Firebase App Distributions to give instructions to your testers about specific app releases. When distributing a release, if you want your test users to know there is a new feature, you can mention the feature along with the use description in the release notes.
I’d suggest creating a release_notes.txt
file in the root of your Flutter project directory (even if its empty right now) and then you can add notes specific to every release you distribute. It will then be used by Codemagic and sent to Firebase App Distribution, where it will appear for your test users.
testers
- this is a list of email addresses for the testers. For now, just use your own email address so we can test the setup.You can use atestersFile
property instead and specify a file with all of your testers. See the documentation below under References for the syntax.groups
- this parameter specifies the group of testers you have set up in the Firebase console for app distribution. If you have not done this yet, select App Distribution within the Firebase console, on the left side menu. Then select the Testers & Groups tab and create an empty group for now.
Once you have created the group, check the internal name by clicking the information icon next to the name, for example:
groupsFile
parameter instead of groups
to specify a file with all of your testers. See the documentation below under References for the syntax.There are a few parameters to help you select the test users you wish to distribute your app to. During initial setup for a project, I usually use the testers
property to make sure it is configured correctly and working as it should. Then I later change to the groups
property because I like to use the Firebase console to manage the test users for a distribution, as you end up adding/remove people constantly.
If you prefer to control these tester email lists in a file, use the testersFile
or groupsFile
properties.
Local app distribution test
Here we will test the local setup of the Firebase App Distribution Gradle plugin and make sure it is publishing to Firebase App Distribution before we set it up in Codemagic.
First do a release build of your Flutter app locally, to make sure it builds correctly. None of the changes we’ve made should stop a release build, but you may have made some typos so let’s test it just in case.
Now open a terminal window and change into your /android
subdirectory. From that /android
subdirectory run the command exactly as follows:
./gradlew assembleRelease appDistributionUploadRelease
flutter doctor -v
to get your Java runtime location, which on macOS is something like /Applications/AndroidStudio.app/Contents/jre/jdk/Contents/Home/bin/java
. Then add this to your PATH
. If you want to do this for macOS, then this article has the necessary instructions.This command will do a full Gradle release build of your app for Android and then attempt to publish that build to Firebase App Distribution. If there are any issues with your project, they will tend to come out here and the publishing to Firebase App Distribution will fail.
The output is long and it will take a few minutes. If everything worked correctly, your Flutter app release build should have been set up in Firebase App Distribution. In the end, you should see something like this in your terminal:
If something is wrong, you will get a message like this:
Task :app:appDistributionUploadRelease FAILED
This means the build failed, so you need to check for typos in the firebaseAppDistribution
section of the /android/app/build.gradle
file and try again. You need to get this working locally before you set it up in Codemagic.
If everything went well, log in to the Firebase console and select App Distribution from the menu. You should see your distribution that will look something like this (although your version will probably be 1.0.0):
Now that the Firebase App Distribution Gradle plugin is working locally and publishing your app release, we can move on and automate the Codemagic setup.
Set up Codemagic post-publish script
Add a post-publish script into your Codemagic workflow. You can access it from the web interface by clicking on the cog icon after the Publish section at the bottom of your workflow in Codemagic:
Codemagic setup is now very straightforward. All the changes above need to be pushed into your repository. Make sure you do a commit and push all these changes to your repository.
yourappname-6e632def9ad4.json
) that grants full admin access to your Firebase project will get pushed up to your repository.If your repository is private that might be fine for now - but if your repository is public, you might try this method to store the private key as a Codemagic environment variable. Another approach is to use the method from Codemagic documentation to keep Firebase credentials secure in Codemagic under Load Firebase configuration. The code would look like this:
#!/usr/bin/env sh
set -e # exit on first failed command
set -x # print all executed commands to the log
if [ "$CM_BUILD_STEP_STATUS" == "success" ]
then
cd $CM_BUILD_DIR/android
./gradlew assembleRelease appDistributionUploadRelease
fi
TIP: Note that the parameter assembleRelease
should not be needed for the gradlew
command because we will run this script immediately after a Codemagic build of the release and this script only runs if the build was successful. So we don’t want to build the app again. But currently there seems to be an issue that requires this parameter. Later versions of the Gradle plugin may only require the command:
./gradlew appDistributionUploadRelease
Once you have the post-publish script and you have customised the values for your project, run another Codemagic build. Check the Codemagic console for your build and expand the Post-publish script section, and you should see something like this:
This should end in something like this:
In the Firebase web console, once this build is complete, there should be another distribution (in addition to the one we did locally to test) appearing in the Firebase console under App Distribution. This will be in addition to the one that was created when we tested locally so you should see two now (although your version will probably be 1.0.0 and have a different build number):
Congratulations! You can now publish alpha and beta re-releases for Android with ease. But I bet you want to know all about the features of Firebase App Distribution now and what the testers see.
References
Official documentation:
- Firebase App Distribution - the documentation.
- Firebase App Distribution - Gradle documentation for all the command parameters.
- Firebase Release Notes - search for “App Distribution” on the page to see which SDKs have been updated.
Codemagic documentation and helpful blog posts:
- Default read only environment variables contains a list of the default environment variables.
- Adding your own environment variables describes how to add the Firebase token as an environment variable.
- Practical guide: Flutter + Firebase + Codemagic (for Android) gives an overview of setting up basic Firebase support for your app for Android.
This article is written by Mike Hughes.
Mike is a Product Manager, Flutter Developer, GDG Melbourne Organiser and he leads the Flutter Melbourne Meetup group. He likes to build native mobile, web and other digital products for businesses.
You can contact him on Twitter at @mikehughestweet, or at LinkedIn