Categories:
Search articles

Search for articles

Sorry, but we couldn't find any matches...

But perhaps we can interest you in one of our more popular articles?

Practical guide: Flutter + Firebase + Codemagic (for Android)

Apr 23, 2020

Firebase is used around the world today for a variety of purposes, like authentication, databases, and crash logs (amongst other things). But how do you get set up with it in a Flutter project for Android? Lewis Cianci investigates.

If you're reading this article, you probably already know what Firebase is and how it can help. It offers a variety of useful tooling, from a centralised view for your logs to a realtime database.

Getting set up with Firebase for your Android Flutter project requires a bit of work on your part. This procedure isn't rolled into an automatic process or anything for you, but thankfully, once it's set up, it's usually the kind of thing you only have to touch once.

Prerequisites

To get started with Firebase, you'll need:

Firebase console: Project setup

Navigate to the Firebase console and set up a new app.

Adding a new project
Adding a new project

Specify a name for your project and click Continue.

FireTest in my case
FireTest in my case

Next, you will be prompted as to whether you want to enable Google Analytics for this project or not. I usually do enable it because I'm interested in Crashlytics and reporting. Google Analytics for Firebase

If you've chosen to enable Analytics, choose your Analytics account or create a new one when given the option. Then click on Create project.

Google Analytics
Google Analytics

Then your Firebase project will be set up. We can now click on Continue.

Our Firebase project is good to go
Our Firebase project is good to go

After clicking on Continue, we should have a screen that looks like this:

We're ready to add it to our app
We're ready to add it to our app

Configuring our local Flutter app to connect to Firebase

For the purposes of this article, we're going to make a very simple app that uses the classic Counter app example to log our events to Firebase. We'll call this app FireTest.

We can create the app by opening the command prompt (or terminal) and typing flutter new firetest.

By default, your app will get created in the com.example namespace, so my app will be com.example.firetest. If you want to call your app something else (and you should!) you can easily find-and-replace all instances of that ID with the app ID that you do want.

Adding Firebase to our Android Flutter app

We can now continue with the setup process that we saw above. Click on the ‘Android’ icon to get started with adding Firebase to our Flutter app.

In case you navigated away, you can access your Firebase dashboard here, and then just click on the app you had recently created. Firebase console

Fill out your app details. Your details will be different

Then click Register app. Next, you will get a google-services.json file. Google services instructions

It's handy that there are instructions here, but they are very easy to misinterpret when making a Flutter project. You might think that ‘MyApplication’ is the root of your Flutter app, but it's not. It's the root of your Android app within your Flutter application. So let's set our app up with this configuration file.

Firebase: App setup

The root of your Flutter app looks like this:

Flutter app folder structure
Flutter app folder structure

The root of your Flutter app is up at the top, but the root of the Android app is in the android folder (the folder with firetest_android). That's the folder where you want to put the google-services.json file.

Adding Firebase dependencies to the Android app

Now we need to add the Google Services plugin to our Gradle files for the Android app. We can do that by opening the build.gradle file in the android folder and adding the following to the dependencies node:

 classpath 'com.google.gms:google-services:4.3.3' // Google Services plugin

While you're here, you should check that you have google() in both buildscript and allprojects, but in my experience, they are usually already there.

Gradle dependencies
Gradle dependencies

And we're almost done! We just need to apply the Firebase plugin in one other build.gradle file at the android\app\build.gradle location.

We need to add…

apply plugin: 'com.google.gms.google-services' // Google Services plugin

just above the android { line in the build.gradle file. Adding Firebase to the Android app build Gradle

Get FlutterFire plugins

First, we need to add the flutterfire_core dependency to our pubspec.yaml file. In my sample project, I just added this directly under the dependencies key.

dependencies: 
 # Add the dependency for the Firebase Core Flutter SDK 
 firebase_core: ^0.4.0+9 
 flutter: 
sdk: flutter

No matter what Firebase functionality you make use of, you must use install the firebase_core package.

Add the Crashlytics FlutterFire plugins and any other FlutterFire plugins that you intend to use

Firebase offers a wide array of functionalities, so it would be unwise for Google to bundle everything available into one package. Instead, the dependent features are split into different FlutterFire packages. In my case, I'll add the firebase_analytics and firebase_auth packages as an example. After these changes, my pubspec.yaml file looks like this:

dependencies: 

 firebase_core: ^0.4.0+9 
 firebase_analytics: ^5.0.2 
 firebase_auth: ^0.14.0+5 
 cloud_firestore: ^0.12.9+5 
 flutter: 
sdk: flutter

We've now finished our app-specific setup!

Checking that your app is correctly configured

Now we can navigate back to the Firebase console and choose our app that we just made. After you've done this, up at the top there should be an icon that has a <> with an orange circle over it. Click on that, and then click on “Continue SDK Setup".

The button to press
The button to press
“Continue SDK Setup” option
“Continue SDK Setup” option

You can then skip to Step 4 in the process, and the Firebase Console will be waiting to hear from our app.

Firebase waiting on communication from our app
Firebase waiting on communication from our app

Now if you launch your app in the emulator, fairly soon afterwards, this screen should change to show that Firebase can see your app.

Confirmation that Firebase has been added to our app
Confirmation that Firebase has been added to our app

Troubleshooting

When I did the above, I immediately ran into an issue where adding Firebase to my brand-new Flutter Android app made the DEX bytecode file too big. It looked something like this:

trouble writing output: Too many field references: 131000; max is 65536. You may try using --multi-dex option. There are two fixes to this. You can increase the minSdkVersion requirement of your app, but it's not generally a great idea to arbitrarily increase the minimum version of Android your app can be installed on without a good reason. The other is to enable multidex for your app, and that's actually pretty easy.

In your project/android/app/build.gradle file, add multiDexEnabled true under your defaultConfig. In my pristine project, it looks like this:

 defaultConfig { 
 // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 
 applicationId "com.example.firetest" 
 minSdkVersion 16 
 targetSdkVersion 28 
 versionCode flutterVersionCode.toInteger() 
 versionName flutterVersionName 
 multiDexEnabled true // << this is what you need!
 }

You also need to add implementation 'com.android.support:multidex:1.0.3' to the dependencies a little further down the file. So again, in my pristine Flutter app with only Firebase added to it, it looks like this:

 dependencies { 
 implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 
 implementation 'com.android.support:multidex:1.0.3' 
 }

And you're set! You should be able to launch your app now.

Using Firebase Crashlytics

Now that we are set up with Firebase, we can use Crashlytics as an example to show how easy it is to send crash data to Firebase.

Configuring Crashlytics in our application startup

We need to add a couple of lines to the application startup so that Crashlytics is configured to report all uncaught errors, and also so these are sent when the application is in debug mode. In our project, the void main() function in our main.dart is as simple as this:

void main() {
Crashlytics.instance.enableInDevMode = true;
FlutterError.onError = Crashlytics.instance.recordFlutterError;
runApp(MyApp());
}

Next, we'll set up our widget tree to make it so we can easily record a variety of crashes. You can see what our widget tree looks like here.

Then we can build the app, and we will have these buttons:

Many ways to crash our app
Many ways to crash our app

If we click the “Crash” button, then we will see an application crash in our Firebase console (this can take a few minutes to show up).

Our first crash is logged
Our first crash is logged

Now that you're all set up with Firebase on your Flutter app, you can use many of the available Firebase packages within your Flutter.

Configuring our build to use Firebase securely on Codemagic

Now that you have your Crashlytics set up, you might be tempted to just check it all into source control and move on. This may not be a good idea, however—your google-services.json file is how your app identifies with Google that it is who it says it is, and it could potentially be misused if you check it into source control where other people can access it.

So you want to protect this file wherever possible, but you still want it to be used by your project at build time when your CI/CD provider runs the build.

Should we encrypt it and check it in?

I don't think so. If you're trying to keep it safe from unauthorised parties, then someone could still get your encrypted file and just brute force the password, so it's still possible.

Instead, we'll convert the file to Base64, and then when Codemagic runs the build, it will convert it from Base64 back into a usable file.

Converting our Google Services file to Base64

Using openssl, we can easily encode the file to Base64. That's as simple as running the following command in the directory where our google-services.json file is:

openssl base64 -in google-services.json

You should then receive a text representation of your google-services.json file.

Next, in your Codemagic build pipeline, we set theANDROID_FIREBASE_CONFIG environment variable so we can access it during our build.

Be sure to tick the “Secure” option and then click Add.

Next, in your pre-build script section, add this script:

echo $ANDROID_FIREBASE_CONFIG | base64 --decode > $FCI_BUILD_DIR/android/app/google-services.json
echo Decoded google-services.json! Here is the directory after.
ls $FCI_BUILD_DIR/android/app

What is this script doing? We are echoing our secure environment string and piping it in the base64 app installed on Codemagic's build servers. The result is that when the Base64 is decoded, it returns to its normal text content. This is then written to where it is expected for the app to build, in the google-services.json file.

After this, we use ls to list the contents of $FCI_BUILD_DIR/android/app/ to make sure that the file exists. We can use this to troubleshoot or debug if the file doesn't show up as expected.

When we run our build, we'll see this as the output in our pre-build script:

The pre-build script output
The pre-build script output

We can see that our google-services.json has been produced as expected. When our build completes, we'll have our Firebase configured and ready to go.

Conclusion

Firebase provides a lot of ready-to-use functionality in a simple-to-use package. Their free Spark tier allows you to explore and build some really great things without any initial outlay. So try it out and enjoy, and if you build something cool, be sure to tell us what it is in our Slack channel! 🤓


Lewis Cianci is a software developer in Brisbane, Australia. His first computer had a tape drive. He’s been developing software for at least ten years and has used quite a few mobile development frameworks (like Ionic and Xamarin Forms) in his time. After converting to Flutter, though, he’s never going back. You can reach him at his blog, read about other non-fluttery things at Medium, or maybe catch a glimpse of him at your nearest and fanciest coffee shop along with his dear wife.

Practical guide: Flutter + Firebase + Codemagic (for iOS)

How did you like this article?

Oops, your feedback wasn't sent

Latest articles

Show more posts