iOS Advent Calendar 2019の4日目の@shtnkgmです!
本記事ではiOSで開発/本番環境を分けてFirebaseを利用するTipsを紹介します。
環境を分けて利用したいユースケースは以下のようなものが挙げられます。
-
開発/本番環境によって運用者を分けたい
例)開発環境と本番環境を利用するチームが異なる -
開発環境を本番環境と区別することで本番環境に影響なく開発をしやすくしたい
例)テスト時に開発環境へのPush通知を間違って本番環境に送らないようにしたい -
本番環境の計測数値に開発時のものが含まれないようにしたい
例)AnalyticsやPerformance Monitoring, Crashlyticsの分析精度を高めたい
実現方法
Firebaseで開発/リリース環境を分ける
まずはFirebase側の環境を分ける必要があります。Firebase側の環境を分けるには、以下のいずれかの方法で実現できます。
- Firebaseプロジェクトを環境毎に複数作成する
- 同プロジェクト内にアプリを環境毎に複数作成する
プロジェクト単位で分割した場合はユーザー権限設定も個別に行えますが、アナリティクスは同時にまとめて見られなくなるなどの違いがあるので、運用方法を想定して決めると良いかと思います。
GoogleService-Info.plistを環境毎に分ける
通常の設定ではセットアップ時にFirebase ConsoleからGoogleService-Info.plist
という構成ファイルをダウンロードし、それがデフォルトで読み込まれます。
環境毎に構成ファイルは異なるため、構成ファイルを切り替える必要があり、以下の2種類の方法があります。
- 環境毎のGoogleService-Info.plistを別々のディレクトリに配置し、Target MembershipによってTargetで切り替える
- 環境毎のGoogleService-Info.plistを別々のファイル名にする
Targetが環境によって別れていれば前者でも問題ありませんが、後者のファイル名を区別する方法が分かりやすいためオススメです。
別々のファイル名にする例)
- GoogleService-Info-dev.plist(開発環境)
- GoogleService-Info-qa.plist(QA環境)
- GoogleService-Info-release.plist(本番環境)
注意
ファイル名で区別する場合は、デフォルトのGoogleService-Info.plist
というファイル名は利用しないほうが良さそうです。
公式ドキュメントのFirebase / アナリティクスのレポートの信頼性を確保するにアナリティクスが失われる可能性があると記述があります。
環境毎に構成ファイルを指定する
環境毎にTargetが分かれている場合は、Build SettingsのPreprocessor Macros
のマクロで以下のように構成ファイル名を分岐させると良いです。
let configFileName: String
#if DEBUG
configFileName = "GoogleService-Info-dev"
#elseif QA
configFileName = "GoogleService-Info-qa"
#else
configFileName = "GoogleService-Info-release"
#endif
構成ファイルは以下のようにconfigure(options:)
メソッドで指定できます。
guard let filePath = Bundle.main.path(forResource: "Firebase/\(configFileName)", ofType: "plist"),
let options = FirebaseOptions(contentsOfFile: filePath) else {
fatalError("Firebase plist file is not found.")
}
FirebaseApp.configure(options: options)
Crashlyticsを利用する場合
クラッシュ分析用にFirebase Crashlyticsを利用している場合、Fabricの初期設定とシンボルファイル(dSYM)をアップロードする必要があります。
Fabricの初期設定
Fabricの初期設定で以下のRun Scriptを実行する際、GoogleService-Info.plistの名前を変更している場合はコンパイル時にerror: Could not get GOOGLE_APP_ID in Google Services file from build environment
というエラーが発生します。
"${PODS_ROOT}/Fabric/run"
これを避けるためには、各構成ファイルをGoogleService-Info.plistにリネームしたものをビルドディレクトリにコピーします。
# Crashlytics用にGoogleService-Info.plistをビルドディレクトリにコピーする必要があるた
PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/Firebase"
case "${CONFIGURATION}" in
"Debug" )
cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-dev.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;
"QA" )
cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-qa.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;
"Release" )
cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-release.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;
*)
;;
esac
上記のRun ScriptをFabricのRun Scriptより先に実行するように上に配置します。
dSYMファイルのアップロード
dSYMファイルのアップロード処理はFastlaneで自動化すると便利です。
Fastlaneではupload_symbols_to_crashlyticsというアクションが利用できます。
以下のように、アクションのパラメータに構成ファイルのパスやdSYMファイルの保存先を指定します。
upload_symbols_to_crashlytics(
plistName = configuration == "Release" ? "GoogleService-Info-release.plist" : "GoogleService-Info-qa.plist"
gsp_path: "./YourApp/Path/#{plistName}",
dsym_path: ENV['DSYM_PATH']
)
-
gsp_path
には環境毎の構成ファイルのパスを指定します。 -
dsym_path
にはCI環境でビルドした際のdSYMファイルの保存パスを指定します。利用しているCIサービスによっては環境変数として与えられていることもあります。
おわりに
本記事ではiOSで開発/本番環境を分けてFirebaseを運用するTipsについて紹介しました。
Firebaseの環境を複数に分けると、設定を環境毎に柔軟に行える反面、同じ設定をFirebase Consoleで重複して行う必要があるので、手間を減らすいい方法がないかなと思っています。
本記事と関連する内容で何かアドバイスやご意見があればコメントに記載いただけると嬉しいです。
以上iOS Advent Calendar 2019の4日目の記事でした。