The optional Firebase App Distribution iOS and Android SDKs let you display in-app alerts to your testers when new builds of your app are available to install. This guide explains how to use the App Distribution iOS and Android SDKs to create and customize new build alerts for your testers.
Before you begin
If you haven't already, add Firebase to your Android project.
Step 1: Enable the App Distribution Tester API
Select your project in the Google Cloud console.
Under Firebase App Testers API, click Enable.
Step 2: Add App Distribution to your app
The App Distribution Android SDK consists of two libraries:
firebase-appdistribution-api
- The API-only library, which you can include in all build variants.firebase-appdistribution
- The full SDK implementation (optional).
The API-only library lets your code make calls to the SDK. The calls will have no effect if the full SDK implementation is not present.
Declare the dependency for the App Distribution Android SDK in your module
(app-level) Gradle file (usually <project>/<app-module>/build.gradle.kts
or
<project>/<app-module>/build.gradle
). To avoid including the full SDK
implementation's self-update functionality in your Play builds,
add the API-only library dependency to all
build variants.
Only add the full SDK implementation to variants that are intended exclusively
for pre-release testing.
dependencies {
// ADD the API-only library to all variants
implementation("com.google.firebase:firebase-appdistribution-api:16.0.0-beta14")
// ADD the full SDK implementation to the "beta" variant only (example)
betaImplementation("com.google.firebase:firebase-appdistribution:16.0.0-beta14")
}
Looking for a Kotlin-specific library module? Starting with the October 2023 release, both Kotlin and Java developers can depend on the main library module (for details, see the FAQ about this initiative).
Step 3: Configure in-app alerts
The App Distribution Android SDK provides provides the following ways to set up in-app build alerts for your testers:
- A basic alert configuration that comes with pre-built app update and sign-in dialogs to display to testers.
- An advanced alert configuration that allows you to customize your own user interface.
If you're using the App Distribution Android SDK for the first time, we recommend using the Basic Configuration.
Basic configuration
Use updateIfNewReleaseAvailable
to display a pre-built enable alerts
dialog to testers who haven't yet enabled alerts, and then check if a new
build is available. When called, the method enacts the following sequence:
Checks if a tester has enabled alerts. If the tester has not yet enabled alerts, the method prompts the tester to sign in to App Distribution with their Google account.
Checks for newly available builds for the tester to install.
Displays a pre-built alert prompting the tester to update.
If the new build is an Android App Bundle (AAB), redirects the tester to Google Play to complete the update process.
If the new build is an Android application PacKage (APK), the SDK downloads the new build in the background and prompts the tester to install when the download completes. The SDK sends download progress notifications to the user using
NotificationManager
. You can also add your own progress indicator by attaching anonProgressUpdate
handler to theupdateIfNewReleaseAvailable
Task.
You can call updateIfNewReleaseAvailable
at any point in your app. For
example, you can call updateIfNewReleaseAvailable
during the onResume
method of the app's main activity.
The following example checks if the tester enabled alerts and has access to a new build. If these conditions are met, a dialog is displayed when the build is available to install:
Kotlin+KTX
// Copy and paste this into any part of your app - for example, in your main
// activity's onResume method.
val firebaseAppDistribution = FirebaseAppDistribution.getInstance()
firebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener { updateProgress ->
// (Optional) Implement custom progress updates in addition to
// automatic NotificationManager updates.
}
.addOnFailureListener { e ->
// (Optional) Handle errors.
if (e is FirebaseAppDistributionException) {
when (e.errorCode) {
Status.NOT_IMPLEMENTED -> {
// SDK did nothing. This is expected when building for Play.
}
else -> {
// Handle other errors.
}
}
}
}
Java
// Copy and paste this into any part of your app - for example, in your main
// activity's onResume method.
FirebaseAppDistribution firebaseAppDistribution = FirebaseAppDistribution.getInstance();
firebaseAppDistribution.updateIfNewReleaseAvailable()
.addOnProgressListener(updateProgress -> {
// (Optional) Implement custom progress updates in addition to
// automatic NotificationManager updates.
})
.addOnFailureListener(e -> {
// (Optional) Handle errors.
if (e instanceof FirebaseAppDistributionException) {
switch (((FirebaseAppDistributionException)e).getErrorCode()) {
case NOT_IMPLEMENTED:
// SDK did nothing. This is expected when building for Play.
break;
default:
// Handle other errors.
break;
}
}
});
Advanced configuration
Advanced sign-in configuration
The methods signInTester
and isTesterSignedIn
give you more flexibility to
customize your tester's sign-in experience, so that the tester experience can
better match your app's look and feel.
The following example checks whether the tester has already signed into their
App Distribution tester account. This lets you choose to display your
sign-in user interface (UI) only to testers who haven't yet signed in. After
the tester signs in, you can then call updateIfNewReleaseAvailable
to check
whether the tester has access to a new build.
Kotlin+KTX
// Only show sign-in UI if this is the "beta" variant (example).
if (BuildConfig.BUILD_TYPE == "beta" && !firebaseAppDistribution.isTesterSignedIn) {
// Start your sign-in UI here.
}
// Only check for updates if the tester is already signed in (do not prompt).
if (firebaseAppDistribution.isTesterSignedIn) {
firebaseAppDistribution.updateIfNewReleaseAvailable().addOnFailureListener {
// Handle failed update.
}
}
Java
// Only show sign-in UI if this is the "beta" variant (example).
if (BuildConfig.BUILD_TYPE == "beta" && !firebaseAppDistribution.isTesterSignedIn()) {
// Start your sign-in UI here.
}
// Only check for updates if the tester is already signed in (do not prompt).
if (firebaseAppDistribution.isTesterSignedIn()) {
firebaseAppDistribution.updateIfNewReleaseAvailable().addOnFailureListener( e -> {
// Handle failed update.
});
}
From your sign-in UI, when the tester chooses to proceed, call signInTester()
:
Kotlin+KTX
firebaseAppDistribution.signInTester().addOnSuccessListener {
// Handle successful sign-in.
}.addOnFailureListener {
// Handle failed sign-in.
});
Java
firebaseAppDistribution.signInTester().addOnSuccessListener( unused -> {
// Handle successful sign-in.
}).addOnFailureListener(e -> {
// Handle failed sign-in.
});
Advanced update configuration
The methods checkForNewRelease
and updateApp
give you more flexibility to
customize when your tester is prompted to update. You can also customize the
pre-built update dialog and download progress indicator so they can better
match your app's look and feel.
Note that updateApp
doesn't provide download progress indication. This means
that you need to implement your own progress indication using
NotificationManager
, some kind of in-app status display, or some other
approach.
The following example checks whether a new release is available and then
displays a custom UI. Before calling checkForNewRelease
and updateApp
, make
sure that the tester is signed in by using the
advanced sign-in configuration.
Kotlin+KTX
firebaseAppDistribution.checkForNewRelease().addOnSuccessListener { release ->
if (release != null) {
// New release available. Start your update UI here.
}
}.addOnFailureListener {
// Handle failed check for new release. Fails with Status#NOT_IMPLEMENTED
// if built for Play.
}
Java
firebaseAppDistribution.checkForNewRelease().addOnSuccessListener(release -> {
if (release != null) {
// New release available. Start your update UI here.
}
}).addOnFailureListener(e -> {
// Handle failed check for new release. Fails with Status#NOT_IMPLEMENTED
// if built for Play.
});
When the tester chooses to proceed with the update from your update UI, call
updateApp()
:
Kotlin+KTX
firebaseAppDistribution.updateApp()
.addOnProgressListener { updateState ->
// Use updateState to show update progress.
}
Java
firebaseAppDistribution.updateApp()
.addOnProgressListener(updateState -> {
// Use updateState to show update progress.
});
Step 4: Build and test your implementation
Build your app and test your implementation by distributing the build to testers using the Firebase console.
Visit the App Distribution Troubleshooting guide for help with common issues, such as:
- Tester not receiving in-app alerts
- Tester being prompted to sign in to Google more than once