Flutter Flavor— Multiple Environment setup with Firebase

https://www.creative-tim.com/blog/material-design/why-is-flutter-the-ultimate-solution-for-mvp-development/

Feeling weird 😩 while on the search for flutter flavors? Do you need to do multiple environment setups for your projects? I don’t want to waste your precious time reading. Just follow the steps.

Here we go!

I have divided the post into three parts.

Part 1: VSCode Setup

Part 2: Android Setup

Part 3: iOS Setup

Here we are going to create configuration files for multiple environments in VSCode.

Step 1: Create environment.dart file inside the lib folder and paste this code.

//environment.dartclass Environment {
final String secret;
Environment(this.secret);
}
class EnvironmentValue {
static final Environment development = Environment('Development');
static final Environment production = Environment('Production');
}

Step 2: We are going to create files inside the lib folder for different enviroments like development, staging, production, etc. Here am doing only for development and production. First create main_dev.dart file and paste the code.

//main_dev.dartimport 'package:flutter/material.dart';
import 'environment.dart';
import 'main.dart';
void main() => runApp(MyApp(environment: EnvironmentValue.development));

Then create main_prod.dart file and paste this.

//main_prod.dartimport 'package:flutter/material.dart';
import 'environment.dart';
import 'main.dart';
void main() => runApp(MyApp(environment: EnvironmentValue.production));

You need to create Environment variable in the main.dart file for to check whether the current release types. For that,

//main.dartimport 'package:flutter/material.dart';
import 'environment.dart';
class MyApp extends StatelessWidget {final Environment environment;const MyApp({Key key, @required this.environment}) : super(key: key);@overrideWidget build(BuildContext context) {return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(env: environment),
);
}
}

Do the same thing in the MyHomePage class also.

class MyHomePage extends StatefulWidget {final Environment env;
MyHomePage({Key key, this.env}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(""),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'$_counter You are in ${widget.env.secret}',
style: Theme.of(context).textTheme.headline4,),],
),),
}
}

Note: You need to do some changes in the widget_test.dart inside the test folder

await tester.pumpWidget(MyApp(environment: EnvironmentValue.development));  //default development

Step 3: Add configuration JSON file in VSCode.

Create .vscode folder and then create launch.json file. Inside the launch file,

{   
"version": "0.2.0",
"configurations": [
{
"name": "Development",
"request": "launch",
"type": "dart",
"program": "lib/main_development.dart",
"args": [
"--flavor",
"development"
]
},
{
"name": "Production",
"request": "launch",
"type": "dart",
"program": "lib/main_production.dart",
"args": [
"--flavor",
"production"
]
}
]
}

Thats it. VSCode setup is done. 😅

Here we are going to create configuration files setup for multiple environments in Android Studio alone with Firebase.

  1. Add configuration in Android Studio

In Run/Debug Configurations, edit the name with corresponding file name, add Dart entrypoint with file path and add build flavour name.

2. In android/app/build.gradle under “defaultConfig”, add flavorDimensions and productFlavors for your environments

buildTypes {
release {
signingConfig signingConfigs.debug
}
debug {
signingConfig signingConfigs.debug
}
}
flavorDimensions "flavor-type"
productFlavors {
dev {
dimension "flavor-type"
applicationIdSuffix ".dev"
}
prod {
dimension "flavor-type"
applicationIdSuffix ".uat"
versionNameSuffix "-uat"
}
}

Environment setup in the Android Studio is also done 💪. You have to add google-services.json to your for Firebase authentication. Lets do this.

Go back to VSCode…

  1. You need to create folder for release inside the /android/app/src
  2. Now you have both debug(/android/app/src/debug) and release (/android/app/src/release) folders.
  3. Create Firebase projects for both Development and Production. To create that I suggest you to refer this.
  4. After that, you have to create separate environment folders for both debug & release and put your corresponding environment google-services.json in the folders like

5. You need add the following code in /android/app/src/main/kotlin/com/example/flutterEX/MainActivity.kt

package com.ashok.flutterEXimport androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}

6. Add classpath in /android/build.gradle

classpath "com.google.gms:google-services:4.3.3"

7. Finally, add dependencies in pubspec.yaml

dependencies:
flutter:
sdk: flutter
firebase_core: ^0.4.0+9
firebase_analytics: ^5.0.2
firebase_auth: ^0.14.0+5
cupertino_icons: ^0.1.2

All done for Android 👐.

Select Android device and run project using VSCode,

Here we going to create configuration files setup for multiple environments in Xcode along with Firebase.

  1. Create xcconfig files for both development and production. Like dev.xcconfig and prod.xcconfig, and paste this code
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
FLUTTER_TARGET=lib/main_dev.dart
bundle_suffix = .dev

2. Add debug and release configuration in Runner-> info -> Configurations for both Development and Production

3. Add schemes for the environments as Development and Production

4. In Edit scheme , You need change the configurations for Debug and Release.

Make sure for both Development and Production.

Configuration setup in Xcode is over. 😻

  1. Create group for Firebase. Inside that, create Development and Production groups and put your corresponding GoogleService-Info.plist in the groups like

2. Finally, You need to add run script in Targets Runner -> Build Phases -> Run Script. Rename name as “Firebase” and paste this code

if [ "${CONFIGURATION}" == "Debug-dev" ] || [ "${CONFIGURATION}" == "Release-dev" ] || [ "${CONFIGURATION}" == "Release" ]; then
cp -r "${PROJECT_DIR}/Runner/Firebase/dev/GoogleService-Info-dev.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist"
echo "Development plist copied"elif [ "${CONFIGURATION}" == "Debug-prod" ] || [ "${CONFIGURATION}" == "Release-prod" ] || [ "${CONFIGURATION}" == "Debug" ]; then
cp -r "${PROJECT_DIR}/Runner/Firebase/uat/GoogleService-Info-prod.plist" "${PROJECT_DIR}/Runner/GoogleService-Info.plist"
echo "Production plist copied"fi

Go back to VScode…

Select iOS device and Run project using VSCode,

Am done with this 🙌

Meet you again in my upcoming posts. 🍻

 iOS Developer @nfnlabs, Chennai. Here to share best practices learned through my experience. Reach me on https://www.linkedin.com/in/ashokkumar-b-26026913a/