← back to Blog

SERIES:Publish a Production-ready React Native App to Firebase App Distribution Using Fastlane - Part 3

Written by: Victor Bruce

16th May 2021

|

4 min read

a fast track

In part two of our blog series on building a production react-native app and publishing to an application market, we looked at how we can distribute a pre-release version of our app to a group of testers to Firebase App Distribution from the Firebase console.


Even though using Firebase console to distribute your app is simple and straightforward, the steps involved are very repetitive. As programmers, we like to automate repetitive tasks right?😀 In doing so, we will use a tool called Fastlane to perform a series of steps to publish our app to Firebase App Distribution by running a single command.


What is Fastlane?

Fastlane is an open-source tool for automating the development and releasing process of apps (Android and iOS) to the application market. Fastlane gives you the ability to automate every aspect of your development and release workflow such as:

  1. Automatically generate localized screenshots for the app store.
  2. Easily distribute beta builds to testers.
  3. Publish a new release to the app store in seconds.
  4. Dealing with code signing.

Installing Fastlane

System Requirements:

  • Fastlane is officially supported to run on macOS. 🐧 Linux and 🖥️ Windows are partially supported.
  • You should have ruby with versions 2.4 through 2.7 installed on your macOS. Check your version by running the command ruby --version

Managed (macOS/Linux/Windows):

  1. Install Bundler: used to define your dependency on Fastlane. gem install bundler

  2. Install Fastlane sudo gem install fastlane


Homebrew (macOS):

brew install fastlane


Setup Fastlane in Your Project

Currently, the only file we have worked with is our App.js file. At this point whilst setting up Fastlane, we will also structure our react-native project structure by following the steps below:

  1. Create a src folder in the root of your project.

  2. Move App.js file inside the src folder(if vscode fails to automatically change the path to App.js file inside index.js, you will have to do that yourself manually).

/**
* @format
*/
import { AppRegistry } from "react-native";
import App from "./src/App";
import { name as appName } from "./app.json";
AppRegistry.registerComponent(appName, () => App);
  1. Create a folder called fastlane also at the root of the project /fastlane

  2. Lastly, we will create a fastlane file called FastFile inside /fastlane/FastFile

before and after project folder structure


❗️Note: Another approach to creating a fastlane project is to run the command fastlane init and answer all the interactive setup questions to complete the setup.


Building Lanes

Under this section, we will perform the following steps:

  • Build a lane to distribute the App to Firebase App Distribution for Android
  • Add Firebase App Distribution plugin to fastlane configuration
  • Authenticate with Firebase

Build a lane to distribute the App to Firebase App Distribution for Android

  1. First, we will create a platform for Android to define our lanes.
platform :android do
desc "RN Production App"
end
  1. Next we will define a lane called distribute. Under this lane, we will define a series of actions to build and distribute the App to Firebase App Distribution.

Building The Android App

platform :android do
desc "RN Production App"
lane: distribute do
gradle(task: '', project_dir: '', print_command: false, properties: {})
end

Explanation of the code above:

  • On line 3–5, we define a lane called distribute to run series of actions.

  • On line 4, we call Gradle and pass in four(4) important arguments to the gradle() function.

Gradle is a build system responsible for code compilation testing, and deployment.

For gradle to build our code, we will need to pass the task gradle should run, the project directory gradle should run from, and most importantly the properties(store file, store password, key alias, and key password).

platform :android do
desc "RN Production App"
lane :distribute do
gradle(task: 'clean assembleRelease', project_dir: './android', print_command: false, properties: {
"MYAPP_UPLOAD_STORE_FILE" => ENV["MYAPP_UPLOAD_STORE_FILE"],
"MYAPP_UPLOAD_STORE_PASSWORD" => ENV["MYAPP_UPLOAD_STORE_PASSWORD"],
"MYAPP_UPLOAD_KEY_ALIAS" => ENV["MYAPP_UPLOAD_KEY_ALIAS"],
"MYAPP_UPLOAD_KEY_PASSWORD" => ENV["MYAPP_UPLOAD_KEY_PASSWORD"]
})
end
end

Hide Secrets

We cannot expose sensitive information such as the store password, key password, etc in our Fastfile. We will define all our secrets in an env file and add them to a gitignore file so that we don’t commit the env file to a versioning tool like Git and Github.

  1. Create .env file inside the fastlane folder and store all your secrets
MYAPP_UPLOAD_STORE_FILE=*******
MYAPP_UPLOAD_KEY_ALIAS=******
MYAPP_UPLOAD_STORE_PASSWORD=*****
MYAPP_UPLOAD_KEY_PASSWORD=******
FIREBASE_TOKEN=******
  1. Import the dotenv library and .env file in the FastFile.
fastlane_require 'dotenv'
before_all do
Dotenv.overload('.env')
end

The code above imports the dotenv library on line 1 which is used to manage environment variables and the .env file which contains secrets we do not want to expose.

On lines 3–4, we are instructing Fastlane to load our .env file first before any action defined in the FastFile is considered. This will load the values needed by the actions first before running any action.

fastlane_require 'dotenv'
before_all do
Dotenv.overload('.env')
end
platform :android do
desc "RN Production App"
lane :distribute do
gradle(task: 'clean assembleRelease', project_dir: './android', print_command: false, properties: {
"MYAPP_UPLOAD_STORE_FILE" => ENV["MYAPP_UPLOAD_STORE_FILE"],
"MYAPP_UPLOAD_STORE_PASSWORD" => ENV["MYAPP_UPLOAD_STORE_PASSWORD"],
"MYAPP_UPLOAD_KEY_ALIAS" => ENV["MYAPP_UPLOAD_KEY_ALIAS"],
"MYAPP_UPLOAD_KEY_PASSWORD" => ENV["MYAPP_UPLOAD_KEY_PASSWORD"]
})
end
end

Add Firebase App Distribution plugin to fastlane configuration

The next step is to install the Firebase App Distribution plugin. Run the command: $fastlane add_plugin firebase_app_distribution


result after adding firebase_app_distribution plugin


Authenticate with Firebase

The final piece is to add a Firebase App Distribution action block. But before that, we will have to authenticate with Firebase. Below are the following ways to authenticate with Firebase:

  • Sign in to your Google Account via the plugin’s login action
  • Use Firebase service account credentials
  • Sign in using the Firebase CLI

In our case, we will use the method of signing in to a Google Account via the Firebase App Distribution plugin’s login action.

Steps:

  1. Run the following command:

bundle exec fastlane run firebase_app_distribution_login


run the bundle exec fastlane run firebase_app_distribtion_login command
  1. Open the link in a browser.
open the generated link in the browser
  1. When prompted, sign in to your Google Account and grant permission to access your Firebase project. Copy the resulting code from the login browser and paste it into the command line. The login action then prints a refresh token, which the App Distribution plugin uses to authenticate with Firebase.
refresh token


  1. Pass the token from the previous step to the plugin, using either the firebase_cli_token parameter in your FastFile or by setting the FIREBASE_TOKEN environment variable.
paste the copied refresh token here.


Add Firebase App Distribution Action Block

firebase_app_distribution(
app: "1:905732111903:android:7aace3e18e0b5455811f2a",
testers: "tester1@company.com, tester2@company.com",
firebase_cli_token: ENV["FIREBASE_TOKEN"],
release_notes: "Lots of amazing new features to test out!"
)

Pass in your appId, list of testers, firebase CLI token, and release notes.

❗️Note: make sure to hide your Firebase CLI token safely in your .env file.


Running The Lane

In the end, this is how your FastFile should look like:

fastlane_require 'dotenv'
before_all do
Dotenv.overload('.env')
end
platform :android do
desc "RN Production App"
lane :distribute do
gradle(task: 'clean assembleRelease', project_dir: './android', print_command: false, properties: {
"MYAPP_UPLOAD_STORE_FILE" => ENV["MYAPP_UPLOAD_STORE_FILE"],
"MYAPP_UPLOAD_STORE_PASSWORD" => ENV["MYAPP_UPLOAD_STORE_PASSWORD"],
"MYAPP_UPLOAD_KEY_ALIAS" => ENV["MYAPP_UPLOAD_KEY_ALIAS"],
"MYAPP_UPLOAD_KEY_PASSWORD" => ENV["MYAPP_UPLOAD_KEY_PASSWORD"]
})
firebase_app_distribution(
app: "1:905732111903:android:7aace3e18e0b5455811f2a",
testers: "tester1@company.com, tester2@company.com",
firebase_cli_token: ENV["FIREBASE_TOKEN"],
release_notes: "Lots of amazing new features to test out!"
)
end
end

To build and distribute the app to Firebase App Distribution, run the command bundle exec fastlane android distribute


successfully build and distribute the app to FastLane


Apk file uploaded to Firebase app Distribution.


Recap:

In this blog post, we looked at how to:

  1. Install and setup Fastlane in a project
  2. Add a lane to build and distribute our Android version to Firebase App Distribution
  3. Install Firebase App Distribution plug-in
  4. Authenticate with Firebase
  5. Finally, build our App and distribute it to Firebase App Distribution

References: