🌞 はじめに
試行錯誤してこの記事に辿り着かれた皆様、初めまして。
私は友達 🦜 と作っているプロダクトの開発を ReactNative + Expo (Managed workflow) + TypeScript の構成で行っており、
Development環境・Staging環境・商用環境 1 を分けてビルドして Firebase App Distribution(以降、FAD) で手軽に触れるよう整備しています。
EAS Build 自体はブランチ機能が導入されたこともあって大変便利なのですが、FADで配信するまでに様々なエラーに対面したため、調査にかなり時間がかかってしまいました。
備忘録として、同じ場面で困っている方の助けになればと思い、対処法をQiitaへ残すことにしました。
あとアドベントカレンダーの季節なので、初チャレンジしてみました🎄
🐤 ビルド時に発生したエラー
Firebase設定ファイルの no such file or directory
内容
[PREBUILD] yarn run v1.22.19
[PREBUILD] $ /private/var/folders/s1/02tt52h506xb0yfcnrnw48xm0000gn/T/eas-build-local-nodejs/00a4863a-0987-44fb-9861-a4fffaf81aaf/build/client/node_modules/.bin/expo prebuild --no-install --platform android
[PREBUILD] - Creating native directory (./android)
[PREBUILD] ✔ Created native directory
[PREBUILD] - Updating package.json
[PREBUILD] ✔ Updated package.json
[PREBUILD] - Running prebuild
[PREBUILD] [Error: ENOENT: no such file or directory, open '/private/var/folders/s1/02tt52h506xb0yfcnrnw48xm0000gn/T/eas-build-local-nodejs/00a4863a-0987-44fb-9861-a4fffaf81aaf/build/client/google-services.json'] {
[PREBUILD] errno: -2,
[PREBUILD] code: 'ENOENT',
[PREBUILD] syscall: 'open',
[PREBUILD] path: '/private/var/folders/s1/02tt52h506xb0yfcnrnw48xm0000gn/T/eas-build-local-nodejs/00a4863a-0987-44fb-9861-a4fffaf81aaf/build/client/google-services.json'
[PREBUILD] }
[PREBUILD] - Running prebuild
[PREBUILD] ✖ Prebuild failed
[PREBUILD] Error: [android.dangerous]: withAndroidDangerousBaseMod: Cannot copy google-services.json from /private/var/folders/s1/02tt52h506xb0yfcnrnw48xm0000gn/T/eas-build-local-nodejs/00a4863a-0987-44fb-9861-a4fffaf81aaf/build/client/google-services.json to /private/var/folders/s1/02tt52h506xb0yfcnrnw48xm0000gn/T/eas-build-local-nodejs/00a4863a-0987-44fb-9861-a4fffaf81aaf/build/client/android/app/google-services.json. Please make sure the source and destination paths exist.
これが一番調査に時間がかかりました🤯
[RUN_EXPO_DOCTOR] Running "expo doctor"
→ [PREBUILD] yarn run v1.22.22
の途中に、ファイルがコピーできないというエラーで失敗するという現象です。
原因
- Firebaseの設定ファイル(
google-services.json
/GoogleService-Info.plist
)を.gitignore
で除外していた - Android向けの設定ファイル(
google-services.json
)はそのままの名前では使用できない
解説
.gitignore
が参照されるのは EAS のクラウドビルドの話だと思っていたのですが、--local
オプションを付けてローカルでビルドする際にも参照されるようで、ここに記載したファイルはビルド時に読み込むことができずエラーになるようでした。
また、app.config.ts
の googleServicesFile
2 でそれぞれ設定ファイルのパスを指定しますが、AndroidにおいてはFirebaseからダウンロードしたときのデフォルトの名前 google-services.json
を指定するとエラーになってしまいました。
そこで環境ごとにファイル名を変えてパスを指定したところ、問題なくビルドできるようになりました。
今のディレクトリ構成はこんな感じになっています。
Firebaseの設定ファイルをgitで管理してもいいのか!?問題についてですが、
あの pedantic_mono lintを開発されている mono さんは、Firebaseの設定ファイルは公開しても問題ないと仰っています🙆♂️(圧倒的信頼)(私もFlutter触ってます💓)
そもそもプロジェクトのリポジトリはPrivate権限のため、そこまで問題ないとは思いますが。。
Expo側での環境分けのやり方についてですが、app.config.ts
で環境変数からパスを参照するように書いていて、eas.json
で環境ごとの設定ファイルのパスを指定しています。
こうすることで、
eas build --profile development --platform android --local --output 'build/android/dev.apk'
を実行すればDevelopment環境のAPKが、
eas build --profile preview --platform ios --local --output 'build/ios/stg.ipa'
を実行すればStaging環境のIPAがビルドできる!!
といった形になります🙌
※今回の解説に影響しない部分は省略しています
{
"build": {
"development": {
"env": {
"EXPO_PUBLIC_APP_VARIANT": "development",
"GOOGLE_SERVICES_PATH": "./google_services/development/android.json",
"GOOGLE_SERVICES_INFO_PLIST_PATH": "./google_services/development/ios.plist",
}
},
"preview": {
"env": {
"EXPO_PUBLIC_APP_VARIANT": "staging",
"GOOGLE_SERVICES_PATH": "./google_services/staging/android.json",
"GOOGLE_SERVICES_INFO_PLIST_PATH": "./google_services/staging/ios.plist"
}
},
"production": {
const IS_DEV = process.env.EXPO_PUBLIC_APP_VARIANT === "development";
const IS_STG = process.env.EXPO_PUBLIC_APP_VARIANT === "staging";
export default {
expo: {
ios: {
googleServicesFile: process.env.GOOGLE_SERVICES_INFO_PLIST_PATH,
android: {
googleServicesFile: process.env.GOOGLE_SERVICES_PATH,
ちなみに、パスの最初にある ./
は必須です。
これも無いとエラーになってしまいます。
expo-av
のエラー
内容
[RUN_GRADLEW] FAILURE: Build completed with 2 failures.
[RUN_GRADLEW] 1: Task failed with an exception.
[RUN_GRADLEW] -----------
[RUN_GRADLEW] * Where:
[RUN_GRADLEW] Script '/private/var/folders/s1/02tt52h506xb0yfcnrnw48xm0000gn/T/eas-build-local-nodejs/e780229a-f320-471b-89dc-e28545b3a114/build/client/node_modules/expo-modules-autolinking/scripts/android/autolinking_implementation.gradle' line: 408
[RUN_GRADLEW] * What went wrong:
[RUN_GRADLEW] A problem occurred evaluating project ':expo'.
[RUN_GRADLEW] > A problem occurred configuring project ':expo-av'.
[RUN_GRADLEW] > SDK location not found. Define a valid SDK location with an ANDROID_HOME environment variable or by setting the sdk.dir path in your project's local properties file at '/private/var/folders/s1/02tt52h506xb0yfcnrnw48xm0000gn/T/eas-build-local-nodejs/e780229a-f320-471b-89dc-e28545b3a114/build/client/android/local.properties'.
原因
-
brew install openjdk
でインストールできる最新版のJava(23)を使っている -
ANDROID_HOME
の環境変数が未設定
解説
バージョン17のJavaをダウンロード & ANDROID_HOME
の環境変数を設定 の両方を行ったところ、このエラーは発生しなくなりました。
1️⃣ バージョン17のJavaをインストールする
以下のコマンドを実行してインストールしてください。3
既に導入済みの場合は、先に brew remove openjdk
で削除してください。
brew install openjdk@17
インストール後、以下のように出力されたらOKです。
hayato@HayatonoMacBook-Pro client % java --version
openjdk 17.0.13 2024-10-15
OpenJDK Runtime Environment Homebrew (build 17.0.13+0)
OpenJDK 64-Bit Server VM Homebrew (build 17.0.13+0, mixed mode, sharing)
2️⃣ ~/.zprofile
に以下を追記する
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$ANDROID_HOME/bin:$PATH
完了後、source ~/.zprofile
を実行してから再度試すと、問題なくビルドできると思います。
🐔 FADで配信する際に発生したエラー
FADへAPK / IPAをアップロードする際に発生するエラー
内容
There's been an error processing your distribution. Ensure you are uploading a valid IPA or APK and try again.
原因
eas.json
に "simulator": true
を書いたprofileを使っていたこと
解説
実機用のprofileからは "simulator": true
の記述を消してビルドしたところ、問題なくアップロードできました。(エミュレータ用は別のprofileに分けました)
このオプションを書くと、実機用のビルドではなくなり、FAD上へのアップロードもできないようです。
詳しくは以下で解説されていました。
配信コマンド実行時のエラー
内容
firebase appdistribution:distribute
コマンド実行時に発生しました
Error: App Distribution could not find your app 1:xxxxxx:ios:xxxxxx. Make sure to onboard your app by pressing the "Get started" button on the App Distribution page in the Firebase console: https://console.firebase.google.com/project/_/appdistribution
make: *** [publish-development] Error 1
原因
FADで該当アプリの「開始」ボタンが押されていなかった
解説
ブラウザでFADの画面を開き、「開始」ボタンを押してからコマンドを実行することで、無事に配信することができました。
なお、この作業はFADに登録したアプリごとに行う必要があります。
(今回はiOS・AndroidごとにDevelopment・Staging環境を用意したため、計4回ボタンをポチポチしました)
🌚 おわりに
Expoでローカルビルドができることを知ってから、家の mac mini にJenkinsを導入し、特定のブランチにマージされたら自動ビルド・自動配信するシステムを構築しました。
皆さんも良き EAS Build ライフを!
そして良いクリスマスをお過ごしください🎅🎁
-
各環境について
- Development:開発用環境。主に端末とPCをUSBで接続してデバッグする際に使用。
- Staging:プライベート環境。コミュニティ内で動作チェックをする際に使用。
- 商用:ストアでリリースしている環境。
-
参考サイト
- https://docs.expo.dev/eas/environment-variables/#file-environment-variables
- https://docs.expo.dev/versions/latest/config/app/#googleservicesfile-1
-
Homebrewで別のバージョンをインストールする方法
https://qiita.com/gishi_yama/items/ee3526e7e7a922148333#openjdk ↩