在Flutter中设置环境变量

mat*_*rey 17 dart flutter

例如,构建API的客户端,如Twitch.

在Dart CLI二进制文件中,我可以使用通用环境变量或Dart定义变量.例如,将两者用作后备:

main() {
  String clientId = 
      // dart -dCLIENT_ID='abc bin/example.dart
      // This is considered "compiled-into" the application.
      const String.fromEnvironment('CLIENT_ID') ??

      // CLIENT_ID='abc' dart bin/example.dart
      // This is considered a runtime flag.
      Platform.environment['CLIENT_ID'];

  // Use clientId.
}
Run Code Online (Sandbox Code Playgroud)

Flutter是否有办法设置其中一个/两个,特别是......

  • 在开发时间
  • 当运到prod

一旦我弄清楚如何:)很高兴帮助一些文档:)

tat*_*uDn 60

从 Flutter 1.17 开始,您可以根据需要定义编译时变量。

为此,只需--dart-defineflutter runor期间使用参数flutter build

如果需要传递多个键值对,定义--dart-define多次即可:

flutter run --dart-define=SOME_VAR=SOME_VALUE --dart-define=OTHER_VAR=OTHER_VALUE
Run Code Online (Sandbox Code Playgroud)

然后,您可以在代码中的任何位置使用它们,例如:

const SOME_VAR = String.fromEnvironment('SOME_VAR', defaultValue: 'SOME_DEFAULT_VALUE');
const OTHER_VAR = String.fromEnvironment('OTHER_VAR' defaultValue: 'OTHER_DEFAULT_VALUE');
Run Code Online (Sandbox Code Playgroud)

此外,它们也可以用于本机层。

这是一篇解释更多的文章。

  • 请注意“const”是一个要求!请参阅答案中的文章和 https://github.com/flutter/flutter/issues/55870 我无法正常工作,因为我没有意识到 (8认同)
  • 要传递多个键值对,您还可以使用以下语法: `--dart-define=FIRST_VAR=first_value,SECOND_VAR=second_value` (使用逗号,不重复 `--dart-define=`) (3认同)
  • 是否可以在 AppDelegate.swift 中访问此环境变量? (3认同)

Ben*_*rth 16

运行您的应用程序(在flutter run

  • flutter run --dart-define=EXAMPLE_API_ENDPOINT=https://api.example.com/

发布您的应用程序(在flutter build

我的应用程序不允许用户登录我意识到环境变量是应用程序中的空字符串,而不是它们的实际值。

  • iOS: flutter build ipa --dart-define=EXAMPLE_API_ENDPOINT=https://api.example.com/
  • 安卓: flutter build apk --dart-define=EXAMPLE_API_ENDPOINT=https://api.example.com/

--dart-define文档

flutter run --helpflutter build ipa --help--dart-define显示:

Additional key-value pairs that will be available as 
constants from the String.fromEnvironment, bool.fromEnvironment, 
int.fromEnvironment, and double.fromEnvironment constructors. 
Multiple defines can be passed by repeating "--dart-define" 
multiple times.
Run Code Online (Sandbox Code Playgroud)


Uda*_*ghe 13

我使用简单的 shell 脚本来生成 dart 定义。在我的应用程序中,有 3 种构建风格:devstagingprod。环境变量在常规文件中定义.env

\n
env/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dev.env\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 prod.env\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 staging.env\n
Run Code Online (Sandbox Code Playgroud)\n

dart-defines这是从文件生成的脚本.env

\n
#!/bin/bash\n\n# scripts/generate_dart_defines.sh\n\ncase "$1" in\n"dev") INPUT="env/dev.env"\n;;\n"staging") INPUT="env/staging.env"\n;;\n"prod") INPUT="env/prod.env"\n;;\n*)\n  echo "Missing arguments [dev|staging|prod]"\n  exit 1\n;;\nesac\n\nwhile IFS= read -r line\ndo\n  DART_DEFINES="$DART_DEFINES--dart-define=$line "\ndone < "$INPUT"\necho "$DART_DEFINES"\n
Run Code Online (Sandbox Code Playgroud)\n

这是触发构建的脚本。

\n
#!/bin/bash\n\n# build.sh\n\nif [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then\n  echo -e "Missing arguments: [apk|appbundle|ios] [release|debug|profile] [dev|staging|prod]"\n  # invalid arguments\n  exit 128\nfi\n\nDART_DEFINES=$(scripts/generate_dart_defines.sh $3)\n\nif [ $? -ne 0 ]; then\n  echo -e "Failed to generate dart defines"\n  exit 1\nfi\n\necho -e "artifact: $1, type: $2, flavor: $3\\n"\necho -e "DART_DEFINES: $DART_DEFINES\\n"\n\neval "flutter build $1 --$2 --flavor $3 $DART_DEFINES"\n
Run Code Online (Sandbox Code Playgroud)\n

该脚本接受 3 个参数。第一个是神器apkappbundle或者ios。第二个是构建类型releasedebug或者profile。第三个是构建风格,devstagingprod

\n
./build.sh apk release prod\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,您还需要分别为不同的构建风格配置 android 和 ios。\n https://developer.android.com/studio/build/build-variants

\n

https://shockoe.com/ideas/development/how-to-setup-configurations-and-schemes-in-xcode/

\n

https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/ManagingSchemes.html

\n


Joh*_*hiz 11

如果您有多个环境变量,请使用 option --dart-define-from-file=env.json

前任:

flutter build web --dart-define-from-file=env.json
Run Code Online (Sandbox Code Playgroud)

或者

flutter run --dart-define-from-file=env_dev.json
Run Code Online (Sandbox Code Playgroud)

将 env.json 放在 pubspec.yaml 所在的根目录中。

示例 json 文件

  1. 环境.json

    {“backend_url”:“https://server.com”}

  2. env_dev.json

    {“backend_url”:“https://dev.server.com”}

使用示例:

const backendUrl = String.fromEnvironment('backend_url', defaultValue: 'SOME_DEFAULT_VALUE');
Run Code Online (Sandbox Code Playgroud)


Eri*_*del 9

对于配置,我看到的一种常见模式是使用单独的主文件。即

flutter run -t lib/production_main.dart

flutter build apk -t lib/debug_main.dart

然后在这些不同的主文件中设置所需的配置。

就读取ID而言,您可以从任意资产https://flutter.io/assets-and-images/中进行操作

我相信Flutter可以按照您的建议从环境中读取内容,但是我不知道如何在iOS或Android上设置这些环境变量。

  • 如果有人感兴趣,我整理了一个示例应用程序,演示了如何完成此操作[https://github.com/ROTGP/flutter_environments](https://github.com/ROTGP/flutter_environments) (3认同)

小智 8

如果您使用的是Flutter 版本 >= 3.7,您可以通过参数或配置文件两种方式传递环境变量。例如:

flutter run --dart-define=BASE_URL=http://localhost:3000
Run Code Online (Sandbox Code Playgroud)

或者您可以创建一个文件(例如 env.json)并在其中设置所有所需的变量,例如:

{
  "BASE_URL": "http://localhost:3000",
  "TEST_USER": "test_user"
}
Run Code Online (Sandbox Code Playgroud)

然后传递文件:

flutter run --dart-define-from-file=env.json
Run Code Online (Sandbox Code Playgroud)

如果您的 Flutter 版本< 3.7,您只有第一个选项


Sam*_*Nde 7

我确实agree使用了 @tatsuDn 发布的答案,但我想提供一个从 .env 文件加载环境变量的解决方案

.env首先在项目的根文件夹中创建一个文件。
确保将该文件添加到您的pubspec.yamland [git] ignoreit.

.env您的文件应如下所示

API_KEY=sampleapikey
# This line is a comment

# The white line above will be ignored
HEADER=sampleapiheader
ANOTHER_UNIQUE_KEY=theValueOfThisKey
KEY_CONTAINS_#=*234*5#
KEY_CONTAINS_EQUALS=IP8iwe=0&
Run Code Online (Sandbox Code Playgroud)

这是您的资产部分的样子。

# To add assets to your application, add an assets section, like this:
assets:
  - assets/images/
  - assets/flags/
  - .env
Run Code Online (Sandbox Code Playgroud)

最后,通过读取和解析文件来加载环境变量.env,以获得Map<String, String>包含键值对的变量。

Future<Map<String, String>> parseStringToMap({String assetsFileName = '.env'}) async {
  final lines = await rootBundle.loadString(assetsFileName);
  Map<String, String> environment = {};
  for (String line in lines.split('\n')) {
    line = line.trim();
    if (line.contains('=') //Set Key Value Pairs on lines separated by =
        &&
        !line.startsWith(RegExp(r'=|#'))) {
      //No need to add emty keys and remove comments
      List<String> contents = line.split('=');
      environment[contents[0]] = contents.sublist(1).join('=');
    }
  }
  return environment;
}
Run Code Online (Sandbox Code Playgroud)

您可以在代码中放置一个快速按钮来测试环境变量是否已正确加载。

ElevatedButton(
    onPressed: () async {
      final env = await parseStringToMap(assetsFileName: '.env');
      print(env);
    },
    child: Text('Print Environment Variables')
),
Run Code Online (Sandbox Code Playgroud)

这是上面 .env 文件的输出。

>>>I/flutter ( 7182): {API_KEY: sampleapikey, HEADER: sampleapiheader, ANOTHER_UNIQUE_KEY: theValueOfThisKey, KEY_CONTAINS_#: *234*5#, KEY_CONTAINS_EQUALS: IP8iwe=0&}
Run Code Online (Sandbox Code Playgroud)

注意:您需要重新运行应用程序(不是热重载)才能.env加载资源。
您还可以将变量加载到 json 文件中[当您有非字符串环境变量并且不想解析字符串时,这可能会很有帮助。
为了避免 IO,最好只加载一次环境变量,然后使用GetIt.


Ore*_*low 5

由于我也尝试解决此问题,并且遇到了这个线程,所以我只想为将来寻求解决方案的人们添加它...如果您要寻找的是PROD / DEV环境,那么现在有一种受支持的方法获取该应用是否在生产中:

const bool isProduction = bool.fromEnvironment('dart.vm.product');
Run Code Online (Sandbox Code Playgroud)

如建议:

https://twitter.com/FlutterDev/status/1048278525432791041

https://github.com/flutter/flutter/issues/4014