【Mac不要】FlutterアプリにFirebase SDKを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編


# はじめに

※この記事は、以下の記事の続編の一つです。

[【Mac不要】開発中のFlutter製アプリをiOSとAndroidに実機配備する手順 - Codemagic編](https://qiita.com/kami_teru/items/c7ed113d0ecdf7e48ff0)

この記事ではその後、FlutterにFirebase SDKを組み込み、iOS, Androidの両端末からFirebaseコンソールに疎通できるまでの手順を説明します。

Firebase SDKの組み込みを終わらせておくと、以下のようなメリットがあります。

* アプリがいつ、どこで、実行されているかの情報がFirebaseコンソールで確認できる。
* Firebase API([FlutterFire](https://firebaseopensource.com/projects/firebaseextended/flutterfire/))との連携コードの組み込みがスムーズに行える。
* 利用者のGoogleアカウントを利用するための実装(例:[Build a Photo Sharing app with Google Photos and Flutter](https://codelabs.developers.google.com/codelabs/google-photos-sharing/index.html?index=..%2F..index#3))の組み込みがスムーズに行える。

上記から、この手順が開発の土台になるケースが結構あるかと思い、手順にまとめておくことにしました。では早速始めてみましょう。

## 謝辞

#### Codemagic Practical guide

この記事は、Codemagicで提供されている以下の手順を、Macを使わずWindows10で実施した記録です。丁寧なガイドを提供してくださり、ありがとうございます。

* [Practical guide: Flutter + Firebase + Codemagic (iOS) ](https://blog.codemagic.io/practical-guide-flutter-firebase-codemagic/)
* [Practical guide: Flutter + Firebase + Codemagic (Android)](https://blog.codemagic.io/practical-guide-flutter-firebase-codemagic-on-android/)

## 前提

この記事は、以下に当てはまる人向けの iOS/Android 対応アプリにFirebase SDkを組み込む手順を紹介します。

* 開発機はWindowsだ
* **Macを持っていない**
* Flutterで開発したい
* Apple Developer Programに既に登録している。

## 開発環境の前提

以下の記事の手順に沿って、FlutterアプリをCodemagicでビルドし、自身のiOS端末/Android端末にアプリを配備できる状態にしておいてください。

* [【Mac不要】開発中のFlutter製アプリをiOSとAndroidに実機配備する手順 - Codemagic編](https://qiita.com/kami_teru/items/c7ed113d0ecdf7e48ff0)


## ソースコードの公開

この記事の手順で作成したソースコードはGithubで公開しています。併せてご参照ください。
https://github.com/atsuteru/flutter_firebase_0507/tree/Qiita-FirebaseSDK-v1.0

# 本文

## 1) Firebase consoleにAppを登録する

[Firebase console](https://console.firebase.google.com/)にアクセスし、Firebase プロジェクトを追加します。
※アカウントがない場合は、作成してください。

1. プロジェクト名を入力します。
![Firebase コンソール - Google Chrome 2020_05_03 17_09_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/172b5813-4fc1-bd45-f2b8-9f7881f7e2ef.png)
1. Googleアナリティクスは有効にしておきます。
![Firebase コンソール - Google Chrome 2020_05_03 17_09_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/7a80d10c-0fa6-e4dc-24e2-e6fec0ca9ff4.png)
1. Googleアナリティクスアカウントは既定のものを選択します。
![Firebase コンソール - Google Chrome 2020_05_03 17_09_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/d2cb66c3-5761-8034-5b22-647f2e8a5b47.png)

## 2) Firebase AppにAndroidアプリを追加し、FlutterのAndroidプロジェクトにSDKを組み込む

Flutter consoleの作成したAppのページで、Androidアプリを追加します。

その前に1つ、情報が必要です。

この後の手順で、Androidアプリを署名している証明書の「フィンガプリント(SHA1)」を入力する必要があります。以下のコマンドを実行して、Codemagicに登録してあるキーストア(*.jks)の「フィンガプリント(SHA1)」を調べておきましょう。

```powershell:powershell
keytool -v -list -keystore flutter_firebase_0503.jks
キーストアのパスワードを入力してください:
キーストアのタイプ: PKCS12
キーストア・プロバイダ: SUN
キーストアには1エントリが含まれます
別名: flutter_firebase_0503_key
...省略...
証明書のフィンガプリント:
         SHA1: 59:F2:64:83:A9:12:E8:44:02:58:45:73:B7:41:1A:77:8D:32:13:B0
...省略...
```

1. 追加するには、Androidのアイコンをクリックします。
![Firebase コンソール - Google Chrome 2020_05_03 17_15_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/edc6688c-5a0a-c424-e2f6-76e5b447be2c.png)
1. アプリの情報を入力します。Androidパッケージ名は`android/ap/src/profile/AndroidManifest.xml`のpackage属性と同じ値にします。デバッグ用の署名証明書 SHA-1には、調べておいた「フィンガプリント(SHA1)」を入力します。入力後は「アプリを登録」をクリックしましょう。
![Firebase コンソール - Google Chrome 2020_05_03 17_18_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/4e6428e9-14c7-135e-0206-590dabe85a68.png)
1. 次のページでは、設定ファイル```google-services.json```をダウンロードします。<br/>ダウンロードしたファイルは、```プロジェクトルート/android/app/google-services.json```に保存します。保存できたら「次へ」をクリックしましょう。
![Firebase コンソール - Google Chrome 2020_05_03 17_18_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/07119b22-5081-10eb-ea9d-f8c274e1ba22.png)
1. Firebase SDKをAndroidプロジェクトに組み込みます。このページの指示に従って、組み込みましょう。なお「プロジェクトレベルのbuild.gradle」は`android/build.gradle`で、「アプリレベルのbuild.gradle」は`android/app/build.gradle`です。「Add this line」の箇所を「それぞれのブロックの末尾に」追加する形です。また手順「最後に、IDE に表示されるバーの [Sync now] をクリックします。」はスキップして大丈夫です。できたら「次へ」をクリックしましょう。
![Firebase コンソール - Google Chrome 2020_05_03 17_21_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/0c58d6fb-482f-8134-620d-a7d05f23442d.png)
1. 最後に、アプリケーションとの疎通確認のページが表示されます。<br/>疎通確認は後で行うので、ここでは「このステップをスキップ」を選択してください。
![Firebase コンソール - Google Chrome 2020_05_03 17_36_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/f70368ac-bcb8-34b0-4574-bfc109317938.png)

４の手順で、私が編集した結果を下に貼り付けておきます。

```android/build.gradle
buildscript {
    ...省略...
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.0'
        classpath 'com.google.gms:google-services:4.3.3'
    }
}
```

```android/app/build.gradle
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'

android {
   ...(省略)...
}

...(省略)...

dependencies {
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    implementation 'com.google.firebase:firebase-analytics:17.2.2'
}
```

また、プロジェクトに追加した```google-services.json```は、リポジトリに追加されるべきではない情報が含まれています。
以下のように、除外する設定を```android/.gitignore```に追加します。

```android/.gitignore
app/google-services.*
```

その代わり、```google-services.json```は別途、Codemagicに登録する必要があります。ここでは以下のコマンドを実行し、```google-services.json```をbase64形式のファイル```google-services.base64```に変換しておきましょう。

```powershell:powershell
cd $Env:userprofile\source\repos\flutter_firebase\flutter_firebase_0503
openssl enc -base64 -in android/app/google-services.json -out android/app/google-services.base64
```

Android向けの組み込み手順は以上です。次はiOS向けの組み込み手順を行いましょう。

## 3) Firebase AppにiOSアプリを追加し、FlutterのiOSプロジェクトにSDKを組み込む

Flutter consoleの作成したAppのページで、iOSアプリを追加します。

1. 追加するには、iOSのアイコンをクリックします。
![Firebase コンソール - Google Chrome 2020_05_03 17_45_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/8a8d4033-d612-3534-b3ea-4d46608f0204.png)
1. アプリの情報を入力します。iOSバンドルIDは`android/ap/src/profile/AndroidManifest.xml`のpackage属性と同じ値にします。App Store IDは、Apple Store Connectの手順を実施済みの方のみ入力してください。（記事：[【Mac不要】開発中のFlutter製アプリを仲間のiOS端末に実機配備する手順 - Codemagic&TestFlight編](https://qiita.com/kami_teru/items/6d5c9b24f711f1270697)）省略しても、本記事の目的には影響ありません。入力できたら、「アプリを登録」をクリックしましょう。
![Firebase コンソール - Google Chrome 2020_05_03 17_46_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/6edc55d2-86c3-9853-d977-2676bf40282f.png)
1. 次のページでは、設定ファイル```GoogleService-Info.plist```をダウンロードします。ダウンロードしたファイルは、```プロジェクトルート/ios/Runner/GoogleService-Info.plist```に保存します。できたら、「次へ」をクリックしましょう。
![Firebase コンソール - Google Chrome 2020_05_03 17_46_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/5d3a24b7-1df2-814d-d274-550930721a48.png)
1. 次のFirebase SDKの組み込み手順は、iOSの場合は不要です。ビルド時にFlutterが自動的に行ってくれるからです。このページでは何もせず、「次へ」をクリックしましょう。
![Firebase コンソール - Google Chrome 2020_05_03 17_52_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/f538132c-8b60-5e6d-bcc5-d28ac621b3a1.png)
1. 次の初期化コードの追加は必要です。```ios/Runner/AppDelegate.m```に```@import Firebase```と```[FIRApp configure];```を追加しましょう。画面で示される例と、Flutterで作成されたコードは少し違いますので、私が作業した結果を後に貼り付けておきます。参考にしてください。できたら、「次へ」をクリックしましょう。
![Firebase コンソール - Google Chrome 2020_05_03 17_52_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/3204e295-3171-e9f1-51df-e6da99bb6439.png)
1. 最後に、アプリケーションとの疎通確認のページが表示されます。疎通確認は後で行うので、ここでは「このステップをスキップ」を選択してください。
![Firebase コンソール - Google Chrome 2020_05_03 17_52_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/e3851871-9823-54aa-e5b3-ba66376064e7.png)

私が初期化コードを追加した結果を、以下に貼り付けておきます。

```ios/Runner/AppDelegate.m
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"

@import Firebase;

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];
  [FIRApp configure];
  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end
```

あと、iOSの場合は追加でもうひと手間が必要です。実は、設定ファイル```GoogleService-Info.plist```の追加は、本来はMacを使ってXCode上で行わなければなりません。```ios/Runner.xcodeproj/project.pbxproj```に```GoogleService-Info.plist```を認識させるためです。

そこで、そのためのコードを以下に貼り付けておきます。Macを持たない我々は、手作業で追加しましょう。ここが本記事の最大難易度です。集中して乗り越えましょう。

`GoogleService-Info.plist`とコメントがついている行を、該当するsectionに追加します。追加する行は全部で4行だけです。各ブロックの一番最後に追加してください。特に3番目の行は紛らわしいブロックが近くにあるので、ちゃんと目印`97C146E51CF9000F007C117D `を見つけて追記しましょう。もしわかりにくければ、[このコミット](https://github.com/atsuteru/flutter_firebase_0503/commit/e55af10add75168294a2189b3fc63c059d74b1bb#diff-38c5d0dde42025b924ea1bc746fb2cca)も参考にしてください。

```text:ios/Runner.xcodeproj/project.pbxproj

/* Begin PBXBuildFile section */
		C402FAF4F184B60574825BEF /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C402FD7E9DA6F279205D8C27 /* GoogleService-Info.plist */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		C402FD7E9DA6F279205D8C27 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.info; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXGroup section */
		97C146E51CF9000F007C117D = {
			children = (
				C402FD7E9DA6F279205D8C27 /* GoogleService-Info.plist */,
			);
		};
/* End PBXGroup section */

/* Begin PBXResourcesBuildPhase section */
		97C146EC1CF9000F007C117D /* Resources */ = {
			files = (
				C402FAF4F184B60574825BEF /* GoogleService-Info.plist in Resources */,
			);
		};
/* End PBXResourcesBuildPhase section */

```

最後に、プロジェクトに追加した```GoogleService-Info.plist```は、リポジトリに追加されるべきではない情報が含まれています。以下のように、除外する設定を```ios/.gitignore```に追加します。

```text:ios/.gitignore
Runner/GoogleService-Info.*
```

その代わり、```GoogleService-Info.plist```は別途、Codemagicに登録する必要があります。ここでは以下のコマンドを実行し、```GoogleService-Info.plist```をbase64形式のファイル```GoogleService-Info.base64```に変換しておきましょう。

```powershell:powershell
cd $Env:userprofile\source\repos\flutter_firebase\flutter_firebase_0503
openssl enc -base64 -in iOS/Runner/GoogleService-Info.plist -out iOS/Runner/GoogleService-Info.base64
```

iOS向けの組み込み手順も以上です。

次に、FlutterアプリにもFirebase SDKの組み込みを行いましょう。

## 4) FlutterアプリにFirebase SDKを組み込む

と言っても、ライブラリを依存関係に追加するだけです。`pubspec.yaml`の`dependencies`に`firebase_core`を追加しましょう。`flutter`よりも前に挿入するようにしてください。

```yaml:pubspec.yaml
dependencies:
  firebase_core: ^0.4.4+3
  flutter:
    sdk: flutter
```

これでFlutterに対する組み込みもできました。

では、ソースコードの修正をpushするその前に・・・！

Codemagicのビルドの設定を修正しましょう。

## 5) CodemagicにFirebase SDKの組み込みに必要な設定を追加する

### Codemagicのビルドの設定を編集する

Codemagicのビルドの設定ページに移動し、以下の設定を追加します。

#### Environment variables

以下の環境変数を追加します。ファイルの内容は、*.base64ファイルをエディタで開き、全選択＆コピーしたものを貼り付けます。改行もそのまま貼り付けてください。ADDボタンを押すこと、SAVEボタンを押すことを忘れないように。

```
GOOGLE_SERVICE_INFO_ANDROID : android/app/google-services.base64ファイルの内容
GOOGLE_SERVICE_INFO_IOS : iOS/Runner/GoogleService-Info.base64ファイルの内容
```

#### Pre-build script

`Pre-build script`は、`Build`の上の「＋」をクリックすると現れます。そこに以下のスクリプトを追加します。SAVEボタンを押すことを忘れないように。よく似た`Post-test script`に騙されないように。

```bash
#!/bin/bash
echo $GOOGLE_SERVICE_INFO_ANDROID | base64 -d -o android/app/google-services.json
echo $GOOGLE_SERVICE_INFO_IOS | base64 -d -o ios/GoogleService-Info.plist
```

これでCodemagic上のビルドの設定ができました。

ここまで出来たら、ソースコードの修正をコミットし、pushしましょう。Codemagicで自動的にビルドが開始します。

ビルドが完了し、インストール用のメールが届いたら、Firebase consoleとの疎通を確認していきましょう。

## 6) Firebaseコンソールとの疎通を確認する

1. Firebase consoleのAndroidアプリのアイコンをクリックし、```SDKの設定を続ける```を選択します。
![Firebase コンソール - Google Chrome 2020_05_03 18_12_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/a0ba5bbc-a55b-8d8c-8b62-07dbe46daa77.png)
1. 設定画面で「次へ」を押下して進み、```アプリを実行してインストールを確認```まで進みます。
1. この状態で、Androidアプリをインストールし、起動、操作、終了を数回繰り返してみてください。<br/>設定画面が以下のように切り替わったら、疎通成功です。<br/>もしうまくいかない場合は、Android端末のアプリの再インストールも試してみてください。
![Firebase コンソール - Google Chrome 2020_05_03 18_14_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/6b544706-633b-3c30-73ba-93b9d6b06613.png)
1. 続けて、Firebase consoleのiOSアプリのアイコンをクリックし、```SDKの設定を続ける```を選択します。
1. 設定画面で「次へ」を押下して進み、```アプリを実行してインストールを確認```まで進みます。
1. この状態で、iOSアプリをインストールし、起動、操作、終了を数回繰り返してみてください。<br/>設定画面が以下のように切り替わったら、疎通成功です。<br/>もしうまくいかない場合は、iOS端末のアプリの再インストールも試してみてください。
![Firebase コンソール - Google Chrome 2020_05_03 18_36_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/ac7e3503-7085-4915-5ce4-e59f69bda1a1.png)

※Androidアプリは、以前のバージョンをアンインストールしないとインストールに失敗するかもしれません。
※iOSアプリは、TestFlightの手順（記事：[【Mac不要】開発中のFlutter製アプリを仲間のiOS端末に実機配備する手順 - Codemagic&TestFlight編](https://qiita.com/kami_teru/items/6d5c9b24f711f1270697)）を実施している場合は、TestFlightから「Update」することでこのバージョンをインストールしましょう。それ以外はの方はCodemagicから届くメールからインストールしてください。

以上で疎通確認は完了です。

## 7) Firebaseコンソールでアプリの利用状況を確認する。

疎通が終われば、アプリのページは次のように「アナリティクス データを待機しています...」と表示されるようになります。これはアナリティクスの集計が１日おきに行われるためです。
![flutter-firebase-0503 - flutter-firebase-0503 - Firebase コンソール - Google Chrome 2020_05_10 20_40_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/60ba7cd4-3c98-ffeb-4ec1-83873e5f8492.png)

一日待つと、このようにAnalyticsが表示されるようになります。
![flutter-firebase-0503 - flutter-firebase-0503 - Firebase コンソール - Google Chrome 2020_05_10 20_13_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/291c579a-2a19-fd8e-5eb0-f88ab9f55a8e.png)

さらにAnalyticsのページでは、こんな情報も見ることができます。
![flutter-firebase-0503 - flutter-firebase-0503 - Firebase コンソール - Google Chrome 2020_05_10 20_18_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109362/482c619d-7844-87ff-8ab9-be82ced6700c.png)

# おわりに

これで、本記事の目的は達成できました。しかし、これだけではまだ何もできませんね。

この記事の続編として、次の２本を予定しているので、乞うご期待！

* Firebase crashlyticsを組み込み、実機で発生したクラッシュ情報をFirebaseコンソールで見れるようにする。<br/>**2020/5/11** 公開しました→ [【Mac不要】FlutterアプリにFirebase Crashlyticsを組み込んでiOSとAndroidに実機配備する手順 - Codemagic編](https://qiita.com/kami_teru/items/67e26b661167863f0b9b)

* Google Photo APIと連携し、利用者のフォトアルバムにアクセスする

最後に、この記事がFlutterを始められる方にとって少しでも助けになれば、幸いです。