こんにちは。株式会社ビデオマーケットの仙台オフィスでMIRAILのiOS/Androidアプリ開発を担当しているasmzです。
今回はちょっとニッチなFirebaseの利用法をご紹介します。
はじめに
皆さんはFirebaseを利用したアプリ開発を行っている時、1つのアプリから複数のFirebaseプロジェクトを使いたくなることはありませんか?ありませんね、わかります。
例えば、開発環境用・本番用など環境毎に複数のFirebaseプロジェクトを用意し、iOS/Androidアプリのビルド時に GoogleService-Info.plist
や google-services.json
を読み替えることで、実際に参照するFirebaseプロジェクトを使い分ける、といったことは結構あるかと思います。
ただ今回はそういう意味の「複数」ではなく、1つのビルドバイナリからFirebaseプロジェクトXとFirebaseプロジェクトY両方とも参照したい、といったケースです。
普通にFirebaseを使っていれば上記のような状況になることはあまりないと思いますが、例えば以下のようにFirebaseプロジェクト自体作り直さないと対応できないような場合、既存のサービスを継続しつつもう一つFirebaseプロジェクトが欲しくなってきます。
- Cloud Firestoreなどで使用するリソースロケーション(リージョン)を変えたい
- Firebaseと統合したGCPプロジェクト側でDatastoreモードを使用しているため、Firebase側のCloud Firestoreが使用できない
このような状況の時、どう対応すれば良いのか今回まとめてみました。
そんなことできるの?
アプリ開発では多くの場合、Firebaseコンソールから出力されるGoogleService-Info.plist
や google-services.json
を自身のアプリプロジェクトに取り込むことでFirebaseを利用しているかと思います。
ただ、これらのファイルは1ファイル内で複数のproject_idを記載できるような形にはなっておらず、またファイル名も決まっていてビルド時に複数ファイルを取り込ませることも難しそうなので、そもそも1アプリから複数のFirebaseプロジェクトを扱える、というイメージがあまり沸かないのではないでしょうか(私がそうでした…)
実はこれ、以下の通り公式でサポートされています。
そのため、公式ドキュメントと内容が重複する部分は多いのですが、以降は細かい説明を加えながらiOS/Androidそれぞれの具体的な設定手順をご紹介します。
事前準備
前提として、アプリが既に何らか1つFirebaseプロジェクトを使用中で、そこに新たなFirebaseプロジェクトを使用したいとします。今回は便宜上これをプライマリ/セカンダリと呼びます。
まず、iOS/Android共にセカンダリのFirebaseプロジェクトへのアプリの追加が必要です。これは通常のFirebaseプロジェクトと同様にFirebaseコンソールから行ってください。(ここでは手順は割愛します)
アプリ追加後にダウンロードできるようになるGoogleService-Info.plist
や google-services.json
は以降の手順でちょっとだけ使うので、どこかに保存しておいてください。
iOSアプリ(Swift)設定手順
セカンダリプロジェクトの設定
以下のようにGoogleService-Info.plist
のファイル内容を見ながら FirebaseOptions
オブジェクトを作成し、そのオブジェクトを使ってセカンダリとなるFirebaseApp
を用意します。
let secondaryOptions = FirebaseOptions( googleAppID: "1:12345678:ios:1234567812345678", gcmSenderID: "12345678901" ) secondaryOptions.apiKey = "your_api_key" secondaryOptions.projectID = "your_project_id" // 以下は必須項目ではないが、利用するFirebase機能に応じて必要なものを設定 secondaryOptions.bundleID = "your.app.bundle.id" secondaryOptions.trackingID = "UA-12345678-1" secondaryOptions.clientID = "12345678901-abcdefg.apps.googleusercontent.com" secondaryOptions.databaseURL = "https://yourproject.firebaseio.com" secondaryOptions.storageBucket = "yourproject.appspot.com" secondaryOptions.androidClientID = "12345.apps.googleusercontent.com" secondaryOptions.deepLinkURLScheme = "yourapp://" secondaryOptions.storageBucket = "your_project_id.appspot.com" secondaryOptions.appGroupID = nil // FirebaseAppへセカンダリ設定(nameは目的に合わせた任意の文字列) FirebaseApp.configure(name: "secondary", options: secondaryOptions) // セカンダリFirebaseApp取得(これを各Firebase機能で使用する) guard let secondary = FirebaseApp.app(name: "secondary") else { assert(false, "Could not retrieve secondary app") }
セカンダリFirebaseの利用
上記で用意したセカンダリFirebaseAppインスタンスを用いることで、セカンダリFirebaseプロジェクトのFirebase各機能を利用することができるようになります。
// Cloud Firestore let secondaryFirestore = Firestore.firestore(app: secondary) // Real Time Database let secondaryDatabase = Database.database(app: secondary) // Functions let secondaryFunctions = Functions.functions(app: secondary) // Storage let secondaryStorage = Storage.storage(app: secondary) // Authentication let secondaryAuth = Auth.auth(app: secondary) // Remote Config let secondaryConfig = RemoteConfig.remoteConfig(app: secondary) // ML Vision let secondaryVision = Vision.vision(app: secondary)
以降はプライマリと同じ形で利用が可能となります。
Androidアプリ(Kotlin)設定手順
セカンダリプロジェクトの設定
Androidの方もgoogle-services.json
を見ながら、iOSと同じようなアプローチでセカンダリFirebaseApp
を用意していきます。
val options = FirebaseOptions.Builder() .setProjectId("your_project_id") .setApplicationId("1:12345678:android:1234567812345678") .setApiKey("your_api_key") // 以下は必須項目ではないが、利用するFirebase機能に応じて必要なものを設定 .setGcmSenderId("12345678901") .setGaTrackingId("UA-12345678-1") .setDatabaseUrl("https://yourproject.firebaseio.com") .setStorageBucket("yourproject.appspot.com") .build() // FirebaseAppへセカンダリ設定(第1引数は Context、第3引数は目的に合わせた任意の文字列) Firebase.initialize(this, options, "secondary") // セカンダリFirebaseApp取得(これを各Firebase機能で使用する) val secondary = Firebase.app("secondary")
セカンダリFirebaseの利用
各Firebase機能の利用方法は以下の通りです。
// Cloud Firestore val secondaryFirestore = Firebase.firestore(secondary) // Real Time Database val secondaryDatabase = Firebase.database(secondary) // Authentication val secondaryAuth = Firebase.auth(secondary) // Functions val secondaryFunctions = Firebase.functions(secondary) // Storage val secondaryStorage = Firebase.storage(secondary) // Remote Config val secondaryConfig = Firebase.remoteConfig(secondary) // ML Vision val secondaryVision = FirebaseVision.getInstance(secondary) // Dynamic Links val secondaryLinks = Firebase.dynamicLinks(secondary)
留意事項
公式ドキュメントに記載がありますが、現状Analyticsは追加Firebaseプロジェクトには対応していません。(デフォルトのプロジェクトにのみログが記録される)
また、公式リファレンスを調べてみたところ、以下の機能についても追加Firebaseプロジェクトを指定するメソッドが用意されていないようなので、現状は対象外と思われます。
- Crashlytics
- Cloud Messaging
- In-App Messaging
- Dynamic Links(iOSのみメソッドが用意されておらず対象外。Androidにはメソッドある)
まとめ
以上がアプリから複数のFirebaseプロジェクトを利用する方法でした。
もともと1つのFirebaseプロジェクトで十分に要件をカバーできるのであれば、その方が良いかと思います。
ただ、既にサービス運用中で今になってプロジェクトの構成変更が効かない場合や、新しい機能追加にあたり新たなデータベースや認証管理が必要になった場合などに、今回のような形でプロジェクトを拡張することができる、という点は覚えておいて損はないかなと思います。