Photo by Rima Kruciene on Unsplash
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.
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
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.
Top comments (0)