How to Load Firebase Config in CodeMagic with Environment Variables

CodeMagic — CI/CD Tool For Flutter

The Problem

I was setting up the repository on GitHub and the CI on CodeMagic for my new Flutter project, which would be using Firebase. I was about to make my initial commit and it hit me. I do not want to put the config JSON (Android) or plist (iOS) on GitHub for the world to see. (It is currently private, but if I open-sourced the project, the details may be in the commit history). So the problem is this. How do I import these files into my CI/CD pipeline to be used as part of the build ready for testing and deployment?

Initially, I thought about storing the files in a separate repository (or a secure location) then clone and move the files into place. Though able, I felt like it required too much scripting for something that should be relatively simple. I must be missing a trick…

I was.

Disclaimer: This all stemmed from an initial pointer on the CodeMagic Slack link here.


The Solution

Prerequisites

  • Created a Firebase project and have the Android and/or iOS config files
  • CodeMagic project

Step 1 — Encode Firebase config files

CodeMagic allows variables to be set up in a workflow which can be used in any part of the build or test process. By using base64 (what is base64?) you can load a JSON file or a plist into a string with no spaces. This makes it easier to assign to variables in scripts.

First off, navigate in the command line to the folder that has your config files in. Most likely one of these, depending on whether it is Android or iOS:

$PROJECT_ROOT/android/app/google-services.json
$PROJECT_ROOT/ios/Runner/GoogleService-Info.plist

Once in the folder, encode the file’s contents, following the section for your OS or preference.

Base64 is the same on all machines so you have a few options for creating encoded strings, which I will detail below.

Mac

openssl base64 -in GoogleService-Info.plist    #ios
openssl base64 -in google-services.json #android

Linux

base64 sample.txt

Windows

It seems you have to create a file as output. You will just need the output file’s contents for the next step.

certutil -encode inputFileName encodedOutputFileName

Web

Use at your discretion. I do not know what they do with the data they encode — I would not recommend this method foot anything enterprise/business related but hobby projects may be ok but try one of the above options first.

https://www.base64encode.org/

Step 2 — Create environment variable(s) in the workflow

Now that you have the encoded values from step 1. Got to CodeMagic. Open your project and got to “Settings” and click and expand “Environment Variables”.

Enter the name of the variables you wish into “variable name” then paste the base64 encoded values in the “variable value”.

Tip: Make sure you click the tick to the right of the value box when you are done. Otherwise, these will not be saved, when you click save.

Once all values are confirmed click “Save”.

Environment variable input screen

Step 3 — Decode and Create File for Build

In the pre-build section of your workflow (works in other sections if you would prefer). Click the “+” icon and in the expanded area enter the following (ensuring the environment variable names match that of the ones you created in step 2).

#!/bin/sh
echo $ANDROID_FIREBASE_JSON | base64 --decode > $FCI_BUILD_DIR/android/app/google-services.json
echo $IOS_FIREBASE_JSON | base64 --decode > $FCI_BUILD_DIR/ios/Runner/GoogleService-Info.plist

Once entered it should look something like this.

Pre-build script to decode environment variables and create config files

Once happy, click “Save”.

Fix: base64 command not found

If when running your workflow you get an error saying base64 command not found the fix is as follows. This issue occurs because Medium adds some Unicode characters that the browser does not visually render and if you copy and paste the above snippet the Unicode characters are copied too. To solve this, clear the spaces between base64 and --decode(by using the backspace key until the 4 in base64 deletes — as this signals that all Unicode characters are deleted) then add the 4 and the space back in again.

Step 4 — Done!

You are good to go. Go and click “Build” and watch the magic happen!

A Little Bonus

If you want to have the files in your project locally but do not want to commit them to GitHub (or other), just add the following to your .gitignore file.

# Firebase
/android/app/google-services.json
/ios/Runner/GoogleService-Info.plist

Video Demo

Thanks to Jonas De Vrient for creating a video of this guide

https://youtu.be/JBDfmP2NDWo

Conclusion

The use of environment variables combined with base64 can result in some quite useful additions allowing for more flexible workflows — for examples, development build, production build etc.

Any questions feel free to comment or Slack me (George Herbert) on the CodeMagic Slack.