iTranslated by AI
[React Native] Distributing to Firebase App Distribution via GitHub Actions (Android Only)
Overview
In this article, I will walk through the process of distributing an existing React Native app—which currently only runs on Expo Go—to Firebase App Distribution specifically for Android.
This is a method to generate, build, and distribute an Android project without using EAS.
Environment
The environments assumed for this walk-through are as follows. In this guide, we will proceed with the goal of distributing the DEV version of the app.
| DEV | PROD | |
|---|---|---|
| App Name | AppName (Dev) | AppName |
| BundleID | com.my.app.dev | com.my.app |
Preparation
Generating the android Directory
Generate the android directory using the following command. The -p flag specifies the platform (android in this case), and we explicitly specify the use of yarn.
expo prebuild -p android --yarn
prebuild creates the android/ directory using the Continuous Native Generation (CNG) mechanism.
Modifying android/app/build.gradle
Add the flavor and signingConfigs settings.
android {
// ....
flavorDimensions "flavor-type"
productFlavors {
dev {
dimension "flavor-type"
applicationId "com.my.app.dev"
resValue "string", "app_name", "AppName (Dev)"
}
prod {
dimension "flavor-type"
applicationId "com.my.app"
resValue "string", "app_name", "AppName"
}
}
signingConfigs {
release {
if (System.getenv()["CI"]) {
storeFile file(System.getenv()["KEYSTORE_PATH"])
storePassword System.getenv()["KEYSTORE_PASSWORD"]
keyAlias System.getenv()["KEYSTORE_KEY_ALIAS"]
keyPassword System.getenv()["KEYSTORE_KEY_PASSWORD"]
} else {
// ...
}
}
}
}
Creating app.config.js
Create app.config.js with the following content to override specific parts of app.json.
export default ({ config }) => {
const isProduction = process.env.APP_ENV === 'production';
return {
...config,
expo: {
name: isProduction ? 'AppName' : 'AppName (Dev)',
ios: {
bundleIdentifier: isProduction ? 'com.my.app' : 'com.my.app.dev',
},
android: {
package: isProduction ? 'com.my.app' : 'com.my.app.dev',
},
},
};
};
Working in the Firebase Console
In the console of the target Firebase project, select "Add app" and fill in the required fields.

For now, "Register app", download google-services.json, and proceed to the end.
Next, go to the "App Distribution" screen and click "Get started". Click "Add group" under "Testers & Groups".

In this case, I created a group named "Developer".

Finally, register testers by entering their email addresses in "Add testers".
Creating a Service Account Authentication File
To perform authentication for your Firebase project, open the Google Cloud Service Accounts page and select the target project. Next, click "Create Service Account", fill in the "Service account name" and "Service account ID", and then select "Create and Continue".

For the role in the next step, select "Firebase App Distribution Admin SDK".

Finally, click "Done" to register the service account.
Select "Manage keys" from the menu of the created service account.

Select "Add Key" > "Create new key".

Confirm that the key type is "JSON", and click "Create" to download and save the JSON file.

Generating a Keystore for Distribution
Generate a keystore for distribution. Replace the XXXXX parts as appropriate.
$JAVA_HOME/bin/keytool -J-Dkeystore.pkcs12.legacy -genkey -v -keystore dev.keystore -keyalg RSA -storepass XXXXX -alias XXXXX -validity 9125 -dname "CN=Developer, O=XXXX, C=Japan"
Registering GitHub Repository Secrets
Register the following secrets.
| SECRET Name | Value |
|---|---|
| ANDROID_KEYSTORE_FILE | The keystore created earlier converted to base64: `cat dev.keystore |
| ANDROID_KEYSTORE_PASSWORD | The password set during keystore generation |
| KEYSTORE_KEY_ALIAS | The alias set during keystore generation |
| ANDROID_KEY_PASSWORD | The password set during keystore generation |
| FIREBASE_APP_ID | Available in the Firebase console: Project settings → General → Android apps → App ID |
| FIREBASE_SERVICE_CREDENTIALS_JSON | The content of the service account authentication file (copy/paste) |
GitHub Actions
I created the final GitHub Actions configuration file for beta distribution as .github/workflows/deploy.yml with the following content.
name: Firebase App Distribution
on:
workflow_dispatch:
push:
branches:
- "develop"
jobs:
distribute:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Read version settings from the volta field in package.json
- uses: volta-cli/action@v4
with:
package-json-path: "package.json"
- name: Cache Yarn
uses: actions/cache@v4
with:
path: ~/.yarn/cache
key: yarn-${{ hashFiles('yarn.lock') }}-${{ runner.os }}
restore-keys: yarn-${{ hashFiles('yarn.lock') }}-
- name: Install dependencies
run: yarn install --frozen-lockfile --network-timeout 300000
# Android SDK & Cache
- uses: android-actions/setup-android@v3
with: { cache: true }
# JDK + Gradle (Build/Configuration Cache enabled)
- uses: gradle/actions/setup-gradle@v3
# Restore the previously created keystore
- name: Write dev.keystore
env:
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
run: |
echo "$ANDROID_KEYSTORE_FILE" | base64 --decode > android/app/dev.keystore
- name: Bump gradle version code
uses: chkfung/android-version-actions@v1.2.1
with:
gradlePath: android/app/build.gradle
versionCode: ${{github.run_number}}
# Replace the key alias with the one configured during creation
- name: Build with Gradle
env:
CI: true
KEYSTORE_PATH: dev.keystore
KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
KEYSTORE_KEY_ALIAS: xxxxxx
KEYSTORE_KEY_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
run: cd android && ./gradlew assembleDevRelease
- name: Upload a Build Artifact
id: upload_artifact
uses: actions/upload-artifact@v4
with:
name: app-dev-release
path: android/app/build/outputs/apk/dev/release/app-dev-release.apk
- name: Deploy to Firebase App Distribution
uses: wzieba/Firebase-Distribution-Github-Action@v1
with:
appId: ${{ secrets.FIREBASE_APP_ID }}
serviceCredentialsFileContent: ${{ secrets.FIREBASE_SERVICE_CREDENTIALS_JSON }}
groups: Developer
file: android/app/build/outputs/apk/dev/release/app-dev-release.apk
- Since I used Volta for version management this time, I am using the following GitHub Action:
With this, although it's only for Android, I believe you will be able to perform beta distribution to Firebase App Distribution.
Reference URLs
Discussion