How to set environment variables in Flutter: a cleaned way
Tags: flutter, tutorial, development, configuration
Published: 2023-09-14 22:18:10

> Photo by <a href="https://unsplash.com/es/@rimakruciene?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Rima Kruciene</a> on <a href="https://unsplash.com/es/fotos/gpKe3hmIawg?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
  
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/po7nxy7wku3u9nrgag0f.png)


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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zugq00khpgvoumwnht81.png)

![Entry for Staging]
(https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ggwuxp2q2g0lfh368zj.png)

![I have one entry for each environment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grst2kssfl8ta5ew7y0x.png)]

![Run for Staging](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bpk3uf6ycwmke6abqdst.png)

![A simple view with the App version that takes from the Environment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ywlz1d8dj8ay2omwp0c.png)

## 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.