🫢

Expo(React Native)で環境変数を使いたいあなたへ。

2024/11/03に公開1

この記事を読むとわかること・解決すること

  • Publicな環境変数とPrivateな環境変数を.envファイルで管理する方法
  • 環境変数の名前の制約をなくしたい!
  • 「EAS Buildのときになぜか、.envが読み込まれない!」

実験のために作成したリポジトリもあるので、よろしければ参考にしてみてください 👋
https://github.com/zackerms/expo-playground-credential

[宣伝] komichi というアプリを作っています!

「どこ行こうかなぁ〜」と考えてたら休日が終わることってありませんか?
このアプリを使うと、現在地や好きな場所から、自動的に付近の場所を検索してお出かけプランを提案してくれます!
見知った場所でも意外としらないスポットが出てきて面白いですよ!
https://komichi.app

先日、Android版をリリースいたしましたので、Androidユーザの方はぜひインストールお願いします!
https://play.google.com/store/apps/details?id=app.komichi&hl=ja

ローカル開発環境

Publicな環境変数を .env ファイルで管理する

Expoでは .env ファイルに EXPO_PUBLIC_ というプレフィックスをつけて環境変数を登録すると自動的に読み込んでくれます。(公式ドキュメント

// .env
EXPO_PUBLIC_APP_VERSION=1.0.0

参照方法

process.env.EXPO_PUBLIC_APP_VERSION

だいたい、Webの方法と同じですね。

EXPO_PUBLIC_ なんてプレフィックスはつけたくない!

そんな方のための方法も用意されています(すこし煩雑になりますが)

EXPO_PUBLIC_ をつけない場合は process.env から参照することができなくなるので、Expo Constantsというライブラリを用いて参照します。

Expo Constantsをインストール

npx expo install expo-constants

今回、参照したい環境変数

// .env
APP_NAME=sample

Expo Constantsで参照できるようにするためには、app.config.ts で登録してあげる必要があります。

// app.config.ts
import {ConfigContext} from "@expo/config"

export default ({config}: ConfigContext) => {
    config.extra = {
        ...config.extra,
        APP_NAME: process.env.APP_NAME,
    }
    return config;
};

参照方法

import Constants from "expo-constants";

Constants.expoConfig?.extra?.APP_NAME

Privateな環境変数を .env.local ファイルで管理する

一つ前のセクションと全く同じ方法で実現できます。

// .env.local
API_KEY=your_api_key
Constants.expoConfig?.extra?.API_KEY

EASビルド

EASビルドでPrivateな環境変数を登録したい!

ローカルで開発する分には、.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ビルド時に参照できないのです。

この救済措置として、Expo Secretsというものが用意されているのでそれを利用します。

EASのダッシュボードを開くと、Secretsというタブがあり、そこからPrivateな環境変数を登録することができます。

ここで登録された環境変数は、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;
};

.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;
}

EASビルドでPrivateな環境変数を登録したい!(ローカルビルド編)

EASの厄介なところは、ローカルビルドではExpo Credentailを参照することができないという点です。

https://github.com/expo/eas-cli/issues/2392

ただ、ローカルビルドの場合は、.env.local ファイルを読み込むことが可能です。

Appendix

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

zackerzacker

環境変数の管理についてもっといいやり方があるよ!という方がいらしたら
ぜひアドバイスをいただきたいです!