Skip to content

Different configurations for development and production #4014

Closed

Description

@drewwarren

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.

Activity

  1. eseidelGoogle commented on May 18, 2016

    @eseidelGoogle
    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".

  2. drewwarren commented on May 18, 2016

    @drewwarren
    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.

  3. abarth commented on May 18, 2016

    @abarth
    Contributor

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

  4. abarth commented on May 18, 2016

    @abarth
    Contributor

    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.

  5. drewwarren commented on May 18, 2016

    @drewwarren
    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
    
  6. abarth commented on May 18, 2016

    @abarth
    Contributor

    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.

  7. sethladd commented on May 18, 2016

    @sethladd
    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

  8. modified the milestone: on May 20, 2016
  9. eseidelGoogle commented on May 25, 2016

    @eseidelGoogle
    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.

  10. drewwarren commented on May 25, 2016

    @drewwarren
    Author

    That is reasonable. Thanks!

  11. eseidelGoogle commented on May 26, 2016

    @eseidelGoogle
    Contributor

    @drewwarren did the approach work?

  12. 1 remaining item

  13. modified the milestones: , on Jan 30, 2017
  14. Hixie commented on Oct 17, 2017

    @Hixie
    Contributor

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

  15. btastic commented on Jan 24, 2018

    @btastic

    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!

  16. zoechi commented on Jan 25, 2018

    @zoechi
    Contributor

    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.

  17. ROTGP commented on Aug 24, 2018

    @ROTGP

    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

  18. zoechi commented on Oct 15, 2018

    @zoechi
    Contributor

    This now works
    #18829 (comment)

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

    and should work well with tree-shaking.

  19. daadu commented on Oct 22, 2019

    @daadu
    Contributor

    @ROTGP I like the demo application you developed.

    positives are:

    1. default to development.
    2. production and other sensitive configs could be gitignore-d.
  20. jamesdixon commented on Nov 11, 2019

    @jamesdixon

    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/

  21. ch-muhammad-adil commented on Sep 8, 2020

    @ch-muhammad-adil

    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.

  22. github-actions commented on Aug 12, 2021

    @github-actions

    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.

  23. locked as resolved and limited conversation to collaborators on Aug 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions