Unity (Android/iOS) + Firebaseでお手軽にPush Notificationを送信する

UnityでもFirebaseを使えば簡単にPush通知を送れるので、その実装方法を記しておきます。

# 環境
* Unity: 5.5.2f1
* Firebaes Unity SDK: 3.0.1
* Android: 5.0.2
    * Android Studio: 2.3
    * NDK: android-ndk-r10e
* iOS: 10.2.1
    * Xcode: 8.2.1

# Unityの設定

Unity用のFirebase SDKを入れます。あらかじめ[Unity を使用して Firebase Cloud Messaging クライアント アプリを設定する](https://firebase.google.com/docs/cloud-messaging/unity/client)をざっくり読んでおきます。その後、Firebase Unity SDKを先程のページのリンクから取得します。日本語版のリンクは古かったりする場合もあるので、必ず最新のUnity SDKがダウンロード出来ていることを確かめます。

UnityでPush通知を入れたいプロジェクトを開きながら、解凍されたフォルダの`FirebaseMessaging.unitypackage`をダブルクリックしてインポートします。

次に、以下のようなコードを任意のControllerに書きます。
`Firebase.Messaging.FirebaseMessaging.TokenReceived`と`Firebase.Messaging.FirebaseMessaging.MessageReceived`にイベントを追加するとFirebaseがPush NotificationをONにします。

```csharp
public void Start() {
    Firebase.Messaging.FirebaseMessaging.TokenReceived += (s, t) => {};
    Firebase.Messaging.FirebaseMessaging.MessageReceived += (s, t) => {};
}
```



# iOSの設定

まず、iOSのFirebaseの設定で、`開発用APNs証明書`や`本番用APNs証明書(本番の場合)`をアップロードする必要があります。
[こちら](https://firebase.google.com/docs/cloud-messaging/ios/certs)の手順を見て設定します。

Firebaseは以下のように設定できていれば大丈夫です。

![dd.png](https://qiita-image-store.s3.amazonaws.com/0/30079/110fbe04-3b0a-17e8-feaa-43c756c7ed94.png)

この時点でiOSをビルドします。ビルドできたらいったん停止し、以下の設定でPush通知をONにしてから再度ビルドします。

![image](https://qiita-image-store.s3.amazonaws.com/0/30079/8b9b19fb-b998-0cf5-ea0a-6e2826131e92.png)

起動後、Push通知の確認ダイアログが出てくれば設定はできています。アプリを閉じてから、FirebaseのWebコンソール上でPushを送信します。

![image](https://qiita-image-store.s3.amazonaws.com/0/30079/fd04ac1b-b8eb-3ca8-547f-23291962528c.png)

# Androidの設定

Androidは特に設定することなく送信できます。
ただ、[Android 5.0 Lolipop以上で通知アイコンが白くなってしまう問題を解決する](http://qiita.com/syarihu/items/95788cbab9b63100c4fb)があるので、解決したい場合は、[AndroidManifestを編集する](https://firebase.google.com/docs/notifications/android/console-audience#edit-the-app-manifest)といけます。resの画像を設定したい場合は`Plugins/Android/res`以下に画像を設定すればいいかなと思います。

例えば以下のように設定できます。

```
# Assets/Plugins/Android/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="${applicationId}"
          android:versionCode="1"
          android:versionName="1.0">
  <application android:label="@string/app_name"
               android:icon="@drawable/app_icon">
    <meta-data
      android:name="com.google.firebase.messaging.default_notification_icon"
      android:resource="@drawable/push_icon" />
    <meta-data
      android:name="com.google.firebase.messaging.default_notification_color"
      android:resource="@color/colorPush" />
...

# Assets/Plugins/Android/res/values/color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPush">#FFDD33</color>
</resources>

# Assets/Plugins/Android/res/drawable/push_icon.png
任意の画像
```

# まとめ

UnityでさくっとFirebaseのPush通知を使ってメッセージを送信できました。便利です。

# 参考

## iOSエラー対処

### error CS1704: An assembly with the same name `Google.VersionHandler' has already been imported. Consider removing one of the references or sign the assembly

Firebaseをアップグレードしたときに以下のエラーがでましたが、いったん、`Assets/PlayServicesResolver`以下をフォルダごと削除してからインポートするとエラーは出なくなりました。

```
error CS1704: An assembly with the same name `Google.VersionHandler' has already been imported. Consider removing one of the references or sign the assembly
Assets/PlayServicesResolver/Editor/Google.VersionHandler.dll (Location of the symbol related to previous error)
Assets/PlayServicesResolver/Editor/Google.VersionHandler_v1.2.14.0.dll (Location of the symbol related to previous error)

Compilation failed: 1 error(s), 0 warnings
```

### EntryPointNotFoundException: Firebase_App_CSharp_FutureBase_status

Push通知の関係ないですが、RemoteConfigでEditor内で`Firebase.RemoteConfig.FirebaseRemoteConfig.FetchAsync`を呼ぼうとするとエラーがでます。Editor内では呼ばないように処理します。


### Undefined symbols for architecture arm64:"_OBJC_CLASS_$_FIRAnalyticsConfiguration", referenced from: 

[ここ](http://stackoverflow.com/questions/19213782/undefined-symbols-for-architecture-arm64)にあるように、`Other Linker Flags`に$(inherited)をつけてCleanしてから再度ビルドします。

またはPodがうまくはいっていないので、Unityのコンソールでエラーが出ていない事を確認し、再度ビルドします。