Expo(React Native)で環境変数を使いたいあなたへ。
この記事を読むとわかること・解決すること
- Expoでの環境変数のいい感じの管理方法を知りたい!
- 「
eas build/update
のときになぜか、.envが読み込まれない!」
実験のために作成したリポジトリもあるので、よろしければ参考にしてみてください 👋
[宣伝] komichi というアプリを作っています!
「どこ行こうかなぁ〜」と考えてたら休日が終わることってありませんか?
このアプリを使うと、現在地や好きな場所から、自動的に付近の場所を検索してお出かけプランを提案してくれます!
見知った場所でも意外としらないスポットが出てきて面白いですよ!
先日、Android版をリリースいたしましたので、Androidユーザの方はぜひインストールお願いします!
ローカル開発環境
Publicな環境変数を .env ファイルで管理する
Expoでは .env
ファイルに EXPO_PUBLIC_
というプレフィックスをつけて環境変数を登録すると自動的に読み込んでくれます。(公式ドキュメント)
// .env
EXPO_PUBLIC_APP_VERSION=1.0.0
参照方法
process.env.EXPO_PUBLIC_APP_VERSION
だいたい、Webの方法と同じですね。
そして、どうやらEXPO_PUBLIC_
とした場合、環境変数を見に行っている訳ではなく、ビルド時に置き換えを行っているらしいため、process.env.EXPO_PUBLIC_XXX
という書き方でないとだめだそうです(参考)。
// OK
process.env.EXPO_PUBLIC_KEY
// NG
process.env["EXPO_PUBLIC_KEY"]
const { EXPO_PUBLIC_KEY } = process.env
Privateな環境変数を使いたい!
Private な環境変数などは、公開されてほしくないのでEXPO_PUBLIC_
とつけることはできません。 そんな方のための方法も用意されています。
EXPO_PUBLIC_
をつけない場合は process.env
から参照することができなくなるので、Expo Constantsというライブラリを用いて参照します。
Expo Constantsをインストール
npx expo install expo-constants
今回、参照したい環境変数
// .env.local
API_KEY=sample
Expo Constantsで参照できるようにするためには、app.config.ts
で登録してあげる必要があります。
// app.config.ts
import {ConfigContext} from "@expo/config"
export default ({config}: ConfigContext) => {
config.extra = {
...config.extra,
API_KEY: process.env.API_KEY,
}
return config;
};
参照方法
import Constants from "expo-constants";
Constants.expoConfig?.extra?.API_KEY
EAS
EAS Environment variables
EASのダッシュボードを開くと、Environment variables
というタブがあり、そこから環境変数を登録することができます。
引用:https://docs.expo.dev/eas/environment-variables/
環境変数には3つの種類があります
-
Plain Text
- Publicな環境変数
- 登録後もWebコンソールやCLIから中身を閲覧できます
-
Sensitive
- Privateな環境変数
- 登録後もWebコンソールやCLIから中身を閲覧できます
-
Secret
- Privateな環境変数
- 登録後は中身を閲覧できません
ビルド方法
EASを使ったビルド方法には2種類あります。
ビルド方法によって、どの環境変数を参照できるかが変わるので注意が必要です!
-
eas build
- やること:ネイティブモジュールからビルドする
- 参照可能な環境変数
-
.env
ファイルに記録されたEXPO_PUBLIC_
で始まる環境変数 -
eas.json
,eas.json
で定義された環境変数 - EASに登録した Plain Text, Sensitive, Secret
-
-
eas update
- やること:JS部分だけを更新する
- 参照可能な環境変数
-
.env
ファイルに記録されたEXPO_PUBLIC_
で始まる環境変数 - [ローカルで実行時]
.env.*
に記録された環境変数 - [EAS上で実行時] EASに登録した Plain Text, Sensitive, Secret
-
したがって、ビルド時にのみ必要な機密情報(GOOGLE_SERVICES_JSON
など)はSecrets
として登録し、eas update
のときにも必要な機密情報はSensitive
として登録する必要があります。
Production環境でPrivateな環境変数を使いたい!
EAS Buildを使う場合
ローカルで開発するときは、.env
ファイルや.env.local
ファイルを使えば良いのですが、EASビルドを行う場合は話が変わってきます。
公式ドキュメントに以下のような記述があります。
Because your EAS Build job runs on a remote server, these .env files might not be available. For instance, .env files are excluded from your uploaded project if they are listed in .gitignore or not committed to your local version control system.
つまり、.env.local
など .gitignore
で git で管理されていないファイルはEASビルド時に参照できないのです。
そこで、先述した EAS Environment variables を利用します!
ここで登録された環境変数は、EASビルド時に参照することができ、app.config.ts
に登録すると、アプリ内で利用することができます。
// app.config.ts
import {ConfigContext} from "@expo/config"
export default ({config}: ConfigContext) => {
config.extra = {
...config.extra,
API_KEY: process.env.API_KEY,
}
return config;
};
アプリケーション上では以下のように参照できます
Constants.expoConfig?.extra?.API_KEY
// process.env.API_KEY では参照できません
EAS Updateを使う場合
単純にeas update
を実行するとローカルの.env.*
ファイルが読み込まれます。 そして、app.config.ts
上ではその内容を参照することができますが、Constants
でなぜか参照できないという謎仕様があります。
そこで、以下のように、--environment
と指定することで、ローカルの.env
ファイルは参照せずに、EASで管理している環境変数を参照するようにすることができます。
eas update --environment production
参考:https://docs.expo.dev/eas/environment-variables/#use-environment-variables-with-eas-update
.env ファイルから自動で環境変数をEASに登録したい!
Expo Secretへの環境変数の登録はEASダッシュボードからもできますが、CLIを利用して、.env ファイルから自動的に import させることも可能です。
eas secret:push --scope project --env-file .env.local
Firebase(GCP)のサービスアカウントをEASに登録したい
サービスアカウントのクレデンシャルファイルのようなものは環境変数とは違い、扱いが難しくなりがちです。
しかし、EASにはファイルをアップロードする方法もあるためカンタンに管理することができます。
eas secret:create \
--scope project \
--name GOOGLE_SERVICES_JSON \
--type file \
--value ./google-services-android-production.json
--force
このファイルを登録するときは以下のようにするとできます。
// app.config.ts
export default ({config}: ConfigContext) => {
// Firebase
config.android.googleServicesFile = process.env.GOOGLE_SERVICES_JSON || "./google-services-android.json";
config.ios.googleServicesFile = process.env.GOOGLE_SERVICES_PLIST || "./GoogleService-Info.plist";
return config;
}
Appendix
EASビルドでPrivateな環境変数を登録したい!(ローカルビルド編)
EASの厄介なところは、ローカルビルドではExpo Credentailを参照することができないという点です。
ただ、ローカルビルドの場合は、.env.local
ファイルを読み込むことが可能です。
Production環境とStaging環境で参照される環境変数を切り替えたい!
.env ファイルを用いた開発スタイルでは .env.staging
, .env.production
などのように、ファイル名に環境の名前をつけることで、ビルド環境ごとに自動的に読み込む環境変数ファイルを切り替えることが可能でした。 これにより、stagingとproductionで同じ環境変数が利用できるという恩恵があります。
しかし、Expo Secretsを利用すると、そのような切り替えは行ってくれません。
ProductionとStagingで環境変数の名前を分ける必要があります。
ですが、アプリ内のコードで環境ごとに参照する環境変数名を切り替えるということはしたくないです。
そこで、app.config.ts 内で環境に応じで、参照する環境変数を切り替えることで、アプリ内では同じ環境変数で利用できるようにします。
そのために、少しだけ工夫をします。
以下のように今の環境が何かを知れるようにします。
// .env.production
APP_ENV=production
// .env.staging
APP_ENV=staging
Expo Secretsに登録するときには、環境の名前をSURFFIXとして追加します。
// Expo Secrets
API_KEY=production-api-key
API_KEY_STAGING=staging-api-key
これで準備完了です。
app.config.ts で環境に応じて自動的に参照する環境変数の名前が切り替わるようにします。
// app.config.ts
export default ({config}: ConfigContext) => {
const SUFFIX =
config.extra.APP_ENV === "staging"
? "_STAGING"
: "";
config.extra = {
API_KEY: process.env[`API_KEY${SUFFIX}`],
}
}
これによって、参照するときには同じ環境変数名で参照することができます。
Constants.expoConfig?.extra?.API_KEY
Discussion
環境変数の管理についてもっといいやり方があるよ!という方がいらしたら
ぜひアドバイスをいただきたいです!