React NativeのFirebase環境別設定
こんにちは。graphy事業部の遠藤と申します。
ゴールデンウィーク期間中の営業は休業とさせていただいてましたが、本日から営業を再開いたします。 令和も引き続きよろしくお願い致します。
今回はReact Nativeを使ったアプリにFirebaseを導入して、環境別にFirebaseプロジェクトが設定されるように実装した話について記載していきたいと思います。
前準備
Firebaseのプロジェクト作成についての説明は省きます。 まず準備する必要があるのは、Firebaseコンソールからdevelopment/staging/production環境毎に設定するためにプロジェクトを3つ追加します。
1つのプロジェクト設定の中でiOS/Androidの環境別アプリの設定を複数設定するという形でも実装は可能だと思いますが、例えば、dev環境でチェックしているとき、Firebaseコンソールからprd用の設定も混在しているプロジェクトを開いて対応することになってしまいます。
なので、開発中はdev環境についての設定しかないプロジェクトを開いて対応するわけですが、最悪プロジェクト設定内のどの設定を壊したとしてもdev環境のアプリまでに問題を留めることができます。
心理的に考えても、開発者が思い切って設定を変更できるという点で開発が進めやすくなると考えています。
iOSでFirebase設定ファイルを環境別に読み込む
基本的な設定方法はiOSアプリの設定ガイドに従って進めていけば問題ないです。 ただ、工夫をする必要があるところでGoogleService-Info.plistの設定を行う工程があると思います。
development/staging/production環境毎にGoogleService-Info.plistが存在する形になるわけですが、環境別アプリのビルド時に、それぞれのGoogleService-Info.plistが適切に読み込まれるように実装する必要があります。
ガイドどおりに設定すると、以下のようにXcodeプロジェクトのルートに追加する形になります。
しかし、Firebaseの初期化時に読み込まれるのはGoogleService-Info.plistのファイルと固定されてしまっているようで、このままですと環境別に用意されたGoogleService-Info.plistが全部同じファイル名なのでXcodeプロジェクトに配置することができません。
その問題を解決するために、Build Phasesに現在の環境を判定して適切なGoogleService-Info.plistがバンドルされるようなスクリプトを追加します。
スクリプトが走るタイミングは、標準で用意されているCopy Bundle Resourcesの1個前に設定してあります。 スクリプトの名前は何の処理をしているかわかりやすい名前にしておきます。
次に、環境別に準備したGoogleService-Info.plistをフォルダを分けて配置しておきます。
そして肝心のスクリプトの中身は以下のような感じです。
GOOGLESERVICE_INFO_PLIST=GoogleService-Info.plist
GOOGLESERVICE_INFO_DEV=${PROJECT_DIR}/firebase/dev/${GOOGLESERVICE_INFO_PLIST}
GOOGLESERVICE_INFO_STG=${PROJECT_DIR}/firebase/stg/${GOOGLESERVICE_INFO_PLIST}
GOOGLESERVICE_INFO_PRD=${PROJECT_DIR}/firebase/prd/${GOOGLESERVICE_INFO_PLIST}
# Make sure the dev version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_DEV}"
if [ ! -f $GOOGLESERVICE_INFO_DEV ]
then
echo "No Development GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 1
fi
# Make sure the stg version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_STG}"
if [ ! -f $GOOGLESERVICE_INFO_STG ]
then
echo "No Staging GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 1
fi
# Make sure the prod version of GoogleService-Info.plist exists
echo "Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_PRD}"
if [ ! -f $GOOGLESERVICE_INFO_PRD ]
then
echo "No Production GoogleService-Info.plist found. Please ensure it's in the proper directory."
exit 1
fi
# Get a reference to the destination location for the GoogleService-Info.plist
PLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app
echo "Will copy ${GOOGLESERVICE_INFO_PLIST} to final destination: ${PLIST_DESTINATION}"
# Copy over the prod GoogleService-Info.plist for Release builds
if [ "${CONFIGURATION}" == "Release" ] || [ "${CONFIGURATION}" == "Debug" ]
then
echo "Using ${GOOGLESERVICE_INFO_PRD}"
cp "${GOOGLESERVICE_INFO_PRD}" "${PLIST_DESTINATION}"
elif [ "${CONFIGURATION}" == "DevRelease" ] || [ "${CONFIGURATION}" == "DevDebug" ]
then
echo "Using ${GOOGLESERVICE_INFO_DEV}"
cp "${GOOGLESERVICE_INFO_DEV}" "${PLIST_DESTINATION}"
elif [ "${CONFIGURATION}" == "StgRelease" ] || [ "${CONFIGURATION}" == "StgDebug" ]
then
echo "Using ${GOOGLESERVICE_INFO_STG}"
cp "${GOOGLESERVICE_INFO_STG}" "${PLIST_DESTINATION}"
else
echo "Failed to copy GoogleService-Info.plist. Please set valid configuration."
exit 1
fi
スクリプトのロジックをざっくり説明すると、現在のConfigurationから環境を判定してフォルダ別に配置したGoogleService-Info.plistをバンドルするよう処理するスクリプトになります。 環境別のConfigurationの詳細に関してはReact Nativeにおける環境別ビルド設定を参照してください。
AndroidでFirebase設定ファイルを環境別に読み込む
Androidの場合も、基本はAndroidアプリの設定ガイド通りに進めていく形で問題ありません。 iOSの場合と同様に、google-services.jsonという設定ファイルを環境別に読み込む形に実装する必要があります。
React Nativeにおける環境別ビルド設定通りにAndroidの環境別ビルド設定がされている前提でお話すると、iOSのように自前でスクリプトを用意する必要はなく、src内にビルドタイプと同じ名前のフォルダを作ってそれぞれにgoogle-services.jsonを配置して完了となります。
ビルド設定のときもそうでしたが、比較的Android側の設定のほうが既存で準備されている仕組みを利用すればいいだけなので楽ですね。
まとめ
以上がiOS/Androidの環境別Firebase設定についての説明でした。 iOS側が少しだけ面倒ですが、環境別に設定するという目的はこれで達成できると思うので参考になれば幸いです。