Flavors in Flutter Part -2 (Firebase)

Anurag Kumar
FlutterFly
Published in
6 min readSep 14, 2023

Hi Devs 👋🏻

In this part, we learn to configure Firebase in flavors. This is part 2 of my article “Flavors in Flutter”. Those who haven't read part 1 please read part 1 Link below for part 1

https://medium.com/flutterfly-tech/flavors-in-flutter-part-1-9552b0ceb764

Table of Contents

  1. Configuring Firebase for Flavors
  2. Create Firebase Projects
  3. Android Configuration
  4. IOS Configuration
  5. Conclusion
  6. Source Code

Configuring Firebase for Flavors

Each flavor might require a distinct Firebase configuration to ensure that your app interacts with the correct Firebase project. Here’s how you can configure Firebase for different flavors in your Flutter project.

Step 1-Install Firebase Flutter Packages:

  • In your pubspec.yaml file, add the Firebase packages you want to use under dependencies. For example:
dependencies:
flutter:
sdk: flutter
firebase_core: ^latest_version
cloud_firestore: ^latest_version

Step 2- Initialize Firebase in Your App:

  • In your main Dart file (usually main.dart), import the Firebase package:

Create Firebase Projects

Before configuring Firebase for flavors, you’ll need to create separate Firebase projects for each flavor. This allows you to maintain isolation between development and production environments.

  1. Go to the Firebase Console.
  2. Create a new project for each flavor (e.g., Development, Production, QA).
Firebase | Google for Developers
  1. Follow the setup instructions to integrate Firebase with your Android and iOS apps.

Android Configuration

For each flavor, you’ll need to add the appropriate Firebase configuration files to your Flutter project’s Android directory (android/app):

  1. Register your app with each Firebase project with the package name

“Don’t forget to add suffix .qa or .dev in package name respectively”

2. Download the google-services.json file for each configuration

3. Place each configuration file in the respective flavor’s directory, such as android/app/src/dev ,android/app/src/qaand android/app/.

4. Add the plugin as a dependency to your project-level build.gradle file:

        classpath 'com.google.gms:google-services:4.3.13'

5. Then, in your module (app-level) build.gradle file, add both the google-services plugin and any Firebase SDKs that you want to use in your app:

apply plugin: 'com.google.gms.google-services'

By following these steps, you’ll be able to configure Firebase for different flavors in your Flutter app’s Android project. This setup ensures that your app connects to the appropriate Firebase project based on the active flavor.

Verify Configuration

To test things out, I have created a simple database in cloud Firestore in each flavor’s Firebase project

To verify that the Firebase configuration is set up correctly for each flavor, build and run your app for each flavor:

Here is the code for the above:-

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flavor_poc/app_config.dart';
import 'package:flutter/material.dart';

Future<void> runWithAppConfig(AppConfig config) async {
WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp();

runApp(MyApp(
appConfig: config,
));
}

class MyApp extends StatelessWidget {
final AppConfig appConfig;

const MyApp({super.key, required this.appConfig});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: appConfig.appName,
theme: appConfig.themeData,
home: MyHomePage(title: appConfig.appName),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});

final String title;

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
final FirebaseFirestore db = FirebaseFirestore.instance;

Future<dynamic> getFlavorInfo() async {
QuerySnapshot<Map<String, dynamic>> snapshot =
await db.collection('test').get();
List<dynamic> list =
snapshot.docs.map((e) => e.data()["text"]).toList();
return list[0];
}



@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FutureBuilder(
future: getFlavorInfo(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
snapshot.data ?? "",
style: Theme.of(context).textTheme.headlineMedium,
);
} else {
return Text(
"Loading",
style: Theme.of(context).textTheme.headlineMedium,
);
}
}),
],
),
),
);
}
}

Now, we have successfully configured Firebase for different flavors in Android.

IOS Configuration

Configuring Firebase for different flavors (build configurations) in a Flutter app for iOS requires some additional setup. Here’s a step-by-step guide on how to set up Firebase for different flavors in your Flutter iOS app:

  1. Register your app with each Firebase project with a bundle identifier

2. Download the GoogleService-Info.plist file for each configuration

3. Rename the downloaded files to indicate the associated flavor (e.g., GoogleServiceDev-Info.plist, GoogleServiceQa-Info.plist) & leave the prod file as a default name.

4. Open Xcode from the Flutter project & create a config folder and put three subfolders dev, qa & prod respectively.

5. Place each renamed configuration file in their respective subfolders config directory of your Flutter project.

6. Add a new user-defined setting named “FIREBASE_CONFIG_FILE” in Runner Build Settings.

7. Instead of writing the script for configuring the right “GoogleService-Info.plist” file for each configuration, we are writing a function in AppDelegate.swift for that. Here is the code for that:-

import UIKit
import Flutter
import Firebase

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
getFilePath()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}


private func getFilePath() {
if let filePath = Bundle.main.path(forResource: "FIREBASE_CONFIG_FILE", ofType: "plist"),
let options = FirebaseOptions(contentsOfFile: filePath) {
print(options.bundleID)
FirebaseApp.configure(options: options)
}

}
}

The Function getfilePath() will change the “GoogleService-Info.plist” file for each configuration.

Note:- Don’ t forget to import firebase in code

8. Now add a new property or key “options” in api_config.dart.

9. Now put the FirebaseOptions in each main file (e.g., main_dev.dart, main_qa.dart)

10. The last step is to assign options value in “firebase.initializeApp()”.

Configuring Firebase in iOS for flavor was complicated. I hope that you understood well 😀

To verify that the Firebase configuration is set up in IOS correctly for each flavor, build and run your app for each flavor:

Conclusion

In this article, I have explained how to configure Firebase for different flavors in your Flutter app’s iOS project. This setup ensures that your app connects to the appropriate Firebase project based on the active flavor, whether it’s for development or production. I hope that you found some useful information in this article.

❤ ❤ Thanks for reading this article ❤❤

If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.

Source Code Repo

The recipe source code for this example is available here.

Follow me on Medium & LinkedIn

References

  1. Build flavors in Flutter (Android and iOS) with different Firebase projects per flavor

OK BYE 👋👋.

--

--