🐮

【flutter web】firebase hosting .envファイルや環境変数が読み込まれない

に公開

Flutter Web で .env ファイルや環境変数が読み込まれない問題と対処法

前提

  • macOS (M1 MacBook)
  • Flutter 3.32.4(stable)
  • Dart 3.8.1
  • パッケージ: flutter_dotenv

ローカル開発 (flutter run -d Chrome) では .env が正しく読み込まれるが、
flutter build web してデプロイすると .env が読み込まれない。どのような呼び出し方でもwebデプロイしたときは何も値が取れない、そもそも.envが見つからないと言われる
または画面が真っ白になったり以下のようなエラーが出る

Uncaught Error
    at Object.d (main.dart.js:3939:20)
    at Object.aOJ (main.dart.js:6116:9)
    at Ps.lI (main.dart.js:41863:19)
    at main.dart.js:89910:30
        ***


原因

Flutter Web では .env ファイルはビルド成果物に含まれない
flutter_dotenv はあくまで「ローカル開発用の補助」であり、Web ではそのままでは参照できない。

.env を直接配布するのは危険であり、ビルド時に --dart-define で環境変数を注入する必要がある


やったこと

どれもうまく行かなかったのですが以下3つを試しました。
https://zenn.dev/tsukatsuka1783/articles/64c9e06d516a3e
https://pc.gajeroll.com/programming/firebase/firebase-deploy-white

dotenv.envではなくdotenv.getを使うようにする

print(dotenv.env)
print("dotenv.env['BASE_URL'] = ${dotenv.env['BASE_URL']}"); 
print(dotenv.get('BASE_URL'))

出力

{BASE_URL: https://hogehoge.com}
dotenv.env['BASE_URL'] = "https://hogehoge.com"
https://hogehoge.com

解決方法

1. コマンドで直接渡す

flutter build web --dart define=BASE_URL="https://hogehoge.com" --release

コード側では const String.fromEnvironment を使う:

const baseUrl = String.fromEnvironment('BASE_URL');

2. ファイルからまとめて渡す

.env をそのまま読み込む代わりに、--dart-define-from-file を利用する。

.env.json
{
  "BASE_URL": "https://hogehoge.com"
}

ビルドコマンド

flutter build web --release --dart-define-from-file=.env.json

コード側では同様に const String.fromEnvironment を使う。

const baseUrl = String.fromEnvironment('BASE_URL');

まとめ

Flutter Web では .env ファイルはそのまま使えない
flutter_dotenv はローカル開発専用
本番環境では --dart-define / --dart-define-from-file を使ってビルドしてデプロイする

補足

直接、環境変数をベタ打ちしてテストなどをしてまた.envから取り出すようにしてとやっていると、特にwebデプロイ後はキャッシュが残っておりうまく行っているふうにだけ見えることがあるので、webブラウザ側でキャッシュを消える設定にして開発することをおすすめします。

またGithub actionsで環境変数をgithubのsecretから取ってきて自動deployをすることは試していませんが、同様にyamlファイルのデプロイコマンドを編集することで可能だろうと予想しています。

Discussion