Photo by Rima Kruciene on Unsplash

How to set environment variables in Flutter: a cleaned way

Bernardo Iribarne
Nerd For Tech
Published in
3 min readSep 14, 2023

--

Since Flutter doesn’t have a standard way to use environment settings I will share a cleaned way to do it.

I don’t like using plain text files so I design a few classes to manage the environment.

Configuration classes

Let’s see how this look like in our code.

I created a simple AppConfig to show you how it works where I’ve just added a simple variable called appVersion:


abstract class AppConfig {

/// App name
String appName => "My App";

/// App version
String appVersion => "1.0.0";
}

Then I have a concrete AppConfig for each environment where I’ve rewrited the app version:

class AppConfigDev extends AppConfig{

/// App version
String appVersion => "1.0.0-dev";
}

class AppConfigStaging extends AppConfig{

/// App version
String appVersion => "1.0.0-staging";
}

class AppConfigProd extends AppConfig{

/// App version
String appVersion => "1.0.0-release";
}

Environment class

The magic happens in Environment class. When you run your app in Flutter, you can send some parameters to your app, so I will show you how to send the environment you want to execute. Let’s see the Environment class and then I will talk about that parameter.

import '/src/config/app_config_prod.dart';
import '/src/config/app_config.dart';
import '/src/config/app_config_dev.dart';
import '/src/config/app_config_staging.dart';

/// Enumeration type for each environment
enum EnvironmentType {
dev("DEV"), staging("STAGING"), prod("PROD");

final String name;
const EnvironmentType(this.name);
}

class Environment {

/// Implements singleton
Environment._internal();
static final Environment _singleton = Environment._internal();

factory Environment() {
return _singleton;
}

late AppConfig config;

Future<void> initConfig(String environment) async{

config = _getConfig(environment);
}

AppConfig _getConfig(String environment) {
Map<String, AppConfig> factories = <String, AppConfig>{};
factories.putIfAbsent( EnvironmentType.dev.name, () => AppConfigDev() );
factories.putIfAbsent( EnvironmentType.staging.name, () => AppConfigStaging() );
factories.putIfAbsent( EnvironmentType.prod.name, () => AppConfigProd() );

AppConfig? config ;
if( factories.containsKey(environment) ){
config = factories[environment];
}

return config??AppConfigDev();
}

}

This class has a method to initialize the configuration where it receives a string called environment. We are going to send that string to our App from the Run/Debug Configuration or from the command line. So, when we initialize our App, we have to include this code:

await Environment().initConfig(String.fromEnvironment('ENVIRONMENT'));

Run your App with the desired environment

Now when you run your app you have to send a parameter called ENVIRONMENT. You can do it from the command line or from your IDE.

From the command line:

flutter run --dart-define=ENVIRONMENT=DEV
flutter run --dart-define=ENVIRONMENT=STAGING
flutter run --dart-define=ENVIRONMENT=PROD

From Android Studio:

You have to go to “Edit Configurations” and create one entry for each environment. Below you can see some screenshots

Edit Configurations
Entry for Staging
I have one entry for each environment
Run for Staging
A simple view with the App version that takes from the Environment

Conclusion

We have configured our Flutter environment in a cleaned way. We saw a very simple case but you can improve AppConfig to have anything you want to manage as configuration. For example, I use to have the dependency injections in the AppConfig, so I can change the dependencies regarding to the environment, it is very useful to me.

Thanks for reading, Clap if you like it!

Let me know your comments below.

--

--

Bernardo Iribarne
Nerd For Tech

Passionate about design patterns, frameworks and well practices. Becoming a Flutter expert