Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Different configurations for development and production #4014

Closed
drewwarren opened this issue May 18, 2016 · 20 comments
Closed

Different configurations for development and production #4014

drewwarren opened this issue May 18, 2016 · 20 comments

Comments

@drewwarren
Copy link

What is the best way to have different configurations of a flutter application?

When developing my application, or creating builds for internal use, I want my app to make http requests against a development server. When I create a build for end users I want the http requests to go to a production server.

@eseidelGoogle
Copy link
Contributor

I don't think we have a recommended approach at this time. @DaveShuckerow has asked similar of us as well.

It's possible the correct answer is "flutter has no opinion".

@drewwarren
Copy link
Author

Could you possibly add a flag to flutter build/run that would pass supplied arguments to the main() function of our applications when they start up?

Although flutter might not need to have an implicit opinion on building environments I feel the current tooling prevents us from coming up with good solutions on our own.

Some options that I don't like but could work with the current tooling:

  • Maintaining separate branches of our application for different environments
    • Couldn't actually work for my team given our version control infrastructure.
  • Writing a "production" build script that swaps out or alters files before building.

It is possible there is a sane option with the current tooling I am not aware of.

@abarth
Copy link
Contributor

abarth commented May 18, 2016

You should be able to read environment variables from https://api.dartlang.org/1.14.0/dart-io/Platform/environment.html

@abarth
Copy link
Contributor

abarth commented May 18, 2016

I think it would also be reasonable to populate https://api.dartlang.org/1.14.0/dart-io/Platform/executableArguments.html if we don't already.

@drewwarren
Copy link
Author

I can read from Platform.environment, but it doesn't allow me to accomplish what I want. I don't want to change something on the phone to enable dev/production of my app; I want that to be baked into the .apk.

Looking at what some of these values look like on my android emulator:

void main(List<String> args) {
  print("env: ${Platform.environment}");
  print("executableArguments: ${Platform.executableArguments}");
  print("executable: ${Platform.executable}");
  print("args: $args");
  runApp(
  ...
}

flutter run my-flag --my-flag -- --my-flag

I/flutter : env: {PATH: /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ANDROID_BOOTLOGO: 1, ANDROID_ROOT: /system, ANDROID_ASSETS: /system/app, ANDROID_DATA: /data, ANDROID_STORAGE: /storage, EXTERNAL_STORAGE: /sdcard, ASEC_MOUNTPOINT: /mnt/asec, BOOTCLASSPATH: /system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/apache-xml.jar:/system/framework/org.apache.http.legacy.boot.jar, SYSTEMSERVERCLASSPATH: /system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar, ANDROID_PROPERTY_WORKSPACE: 9,0, ANDROID_SOCKET_zygote: 10}
I/flutter : executableArguments: []
I/flutter : executable: null
I/flutter : args: null

@abarth
Copy link
Contributor

abarth commented May 18, 2016

Yeah, I'm suggesting that we provide an API on FlutterView (in Java) to supply an array of Strings that then populates the Platform.executableArguments (or some similar static) in Dart. That would let you send whatever configuration you wanted on startup.

@sethladd
Copy link
Contributor

We might also want to start putting useful values into the Dart "environment", and made available to accessors like https://api.dartlang.org/stable/1.16.0/dart-core/String/String.fromEnvironment.html

e.g. flutter.mode could return "release" or "debug" from String.fromEnvironment

@Hixie Hixie modified the milestone: Flutter 1.0 May 20, 2016
@eseidelGoogle
Copy link
Contributor

I spoke with @abarth just now, he suggested one workaround would be to use the -t argument to flutter build to pass a different main.dart for your different versions.

fluter build apk -t lib/production_main.dart for example.

@drewwarren
Copy link
Author

That is reasonable. Thanks!

@eseidelGoogle
Copy link
Contributor

@drewwarren did the approach work?

@drewwarren
Copy link
Author

Yup. 🍰

@Hixie Hixie modified the milestones: 4: Make shippers happy, 5: Make Hixie proud Jan 30, 2017
@Hixie
Copy link
Contributor

Hixie commented Oct 17, 2017

If launching a different main.dart works, then we shall close this bug!

@Hixie Hixie closed this as completed Oct 17, 2017
@btastic
Copy link

btastic commented Jan 24, 2018

Quick question about this issue: When I use different "main.dart" files, how do I go about having different imports in different files.

For example: I have an import "settings.dart" which gives me a "const url" for a production or development endpoint depending on the given "main.dart".

How can I have it deeper down my application, in say "auth.dart"?

Thanks!

@zoechi
Copy link
Contributor

zoechi commented Jan 25, 2018

There is no way to get different imports depending on what the entry file is. You would need to instantiate different classes with the same interface in the main.dart file and pass them to the location where they are used.
There is a feature "configurable imports" in the Dart pipeline since quite some time that might land eventually that could help here. I wouldn't bet this lands the way you need it during 2018.

@ROTGP
Copy link

ROTGP commented Aug 24, 2018

I'm not sure if any progress has been made on this, but I've put together a sample app demonstrating how this can be done (using custom entry point)... https://github.com/ROTGP/flutter_environments

@zoechi
Copy link
Contributor

zoechi commented Oct 15, 2018

This now works
#18829 (comment)

const bool isProduction = bool.fromEnvironment('dart.vm.product');

and should work well with tree-shaking.

@daadu
Copy link
Contributor

daadu commented Oct 22, 2019

@ROTGP I like the demo application you developed.

positives are:

  1. default to development.
  2. production and other sensitive configs could be gitignore-d.

@jamesdixon
Copy link

After reading a bunch of threads on this, I ended up with the multiple entry point approach as mentioned earlier.

I ended up doing the following:

  1. Used json files for configuration
  2. On app load, I load a specific json config depending on which entry point I call (ex: main.dart vs prod.dart)
  3. I then create a Dart class containing the config from the json file
  4. The Dart file is then exposed the config via get_it but could also easily be done via provider or another mechanism

I went with JSON because I could then exclude the files from my git repo and then recreate them on the fly from env variables set in my CI system.

I wrote a brief article that outlines most of the process: https://flutterigniter.com/env-specific-configuration/

@ch-muhammad-adil
Copy link

After reading a bunch of threads on this, I ended up with the multiple entry point approach as mentioned earlier.

I ended up doing the following:

  1. Used json files for configuration
  2. On app load, I load a specific json config depending on which entry point I call (ex: main.dart vs prod.dart)
  3. I then create a Dart class containing the config from the json file
  4. The Dart file is then exposed the config via get_it but could also easily be done via provider or another mechanism

I went with JSON because I could then exclude the files from my git repo and then recreate them on the fly from env variables set in my CI system.

I wrote a brief article that outlines most of the process: https://flutterigniter.com/env-specific-configuration/

What i feel this answer is good but i have tried below solution and it has given me true when i run in release mode.

       bool isProduction = bool.fromEnvironment('dart.vm.product');
       print("current Evn " + isProduction.toString());

I suggest use of both solution or may be you can just use this above code and change your end point if it is in production.

Now there is no need of creating multiple main.dart files for production and development.

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests