FirebaseとUnityでアプリ開発（ハンズオンみたいなやつ）


<img width="300" src="https://connpass-tokyo.s3.amazonaws.com/thumbs/df/5f/df5f8ec738861ca284bb2cce3a00a7ce.png">
**++注意++**
この記事は、[Unity Fukuoka 14](https://unityfukuoka.connpass.com/event/129962/)のセッション『**FirebaseとUnityでアプリ開発（ハンズオンみたいなやつ）**』の資料になります。



## 概要

[Firebase](https://firebase.google.com)は、徐々にサービスが増えたり定期的にアップデートが行われておりますが、Webやゲーム以外のスマホアプリでは事例があるもの、ゲーム関連ではほぼほぼ事例がありません。
特に個人開発をやっているDeveloperがサーバレスに開発したいときに扱うことが多く、個人的にFirebaseは、大規模なゲーム案件よりもカジュアルゲームや個人開発など向けだなと感じています。

<a href="https://firebase.google.com/products?hl=ja"><img width="400" alt="スクリーンショット 2019-06-16 21.35.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/5f383fec-5cbc-64b3-779b-842859dfe268.png"></a> <a href="https://firebase.google.com/support/release-notes/unity"><img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/0517fb14-1a42-6ee1-2a39-685c0265631b.png"></a>

[Firebase Unity SDK](https://firebase.google.com/docs/unity/setup?hl=ja)では、去年6月に[Cloud Functions](https://firebase.google.com/support/release-notes/unity?hl=ja#cloud-functions_1)と先月5月には[Crashlytics](https://firebase.google.com/support/release-notes/unity?hl=ja#crashlytics_1)がサポートされ、Unityへの対応が手強くとても喜ばしいですが、やはりWebやゲーム以外のスマホアプリの事例からすると印象が薄いように感じてしまいます。
ちなみにFirebase Unity SDKでのCloud Functionsの活用は、以前、UNIBOOK10で執筆していた際にリリースされたため詳細をまとめております。

<a href="https://unity-bu.booth.pm/items/831502"><img width="250" src="https://booth.pximg.net/c/620x620/51922995-8a90-4f1c-ad58-a64224c615d4/i/831502/89ddb96c-f80b-4a7e-b47d-8c608b52cf9d_base_resized.jpg"></a> <a href="https://unity-bu.booth.pm/items/957654"><img width="250" src="https://booth.pximg.net/c/620x620/51922995-8a90-4f1c-ad58-a64224c615d4/i/957654/274ec80a-3549-4756-aa29-c33abd3f9479_base_resized.jpg"></a>

- [UNIBOOK9](https://unity-bu.booth.pm/items/831502) - 第4章 「FirebaseとUnity」
- [UNIBOOK10](https://unity-bu.booth.pm/items/957654) - 第2章 「Firebaseを用いたゲームアプリ開発」

[アナリティクス](https://firebase.google.com/products/analytics/?hl=ja)や[Remote Config](https://firebase.google.com/products/remote-config/?hl=ja)などはよく扱われているものの、[Auth](https://firebase.google.com/products/auth/?hl=ja)・[Functions](https://firebase.google.com/products/functions/?hl=ja)・[Firestor](https://firebase.google.com/products/firestore/?hl=ja)・[Storage](https://firebase.google.com/products/storage/?hl=ja)などの開発中にサーバが必要とする機能はあまり使われていないようだったのでUNIBOOK9での執筆やDevFest2018での登壇で知見をシェアしてきました。

<img width="380" src="https://connpass-tokyo.s3.amazonaws.com/thumbs/99/92/999217445b49de857c698861650cb674.png"> <a href="https://medium.com/google-cloud-jp/%E3%81%BB%E3%81%BC%E9%80%B1%E5%88%8Afirebase-18-09-11-fjug-96a6655b4681"><img width="335" alt="スクリーンショット 2019-06-16 23.23.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/397de19b-f840-6fdf-e226-7214d0bfb855.png"></a>

- [GDG DevFest Tokyo 2018](https://tokyo2018.gdgjapan.org/)
- [Firebaseを使ってゲーム開発をやってみた_GDG DevFest Tokyo 2018](https://speakerdeck.com/gremito/firebasewoshi-tutegemukai-fa-woyatutemita-gdg-devfest-tokyo-2018)


今回も同様に**ゲームやUnityコンテンツでもFirebaseは扱える**ものだと知ってもらい、もっとUnityでFirebaseを使った事例が増えていったらイイなと考えています。

本セッションの目的は、**ゲームやUnityコンテンツの開発時にFirebaseを活用したアプリ開発ができるようになる**です。


### 環境

- macOS Mojave（ver.10.14）
- Unity 2019.1.0f2
- Firebase Unity SDK 6.1.1

### 注意

本セッションでは、[Firebase コンソール](https://console.firebase.google.com/?hl=ja)でのプロジェクトの作り方や扱い方は基本省いて進めていきます。
多くの方々が記事で解説していたり、公式の[Unity プロジェクトに Firebase を追加する](https://firebase.google.com/docs/unity/setup?hl=ja)にガイドラインが解説されているため、そちらを参考に作業をお願いします。


## Firebase Unity SDKについて

まずは、公式の[Unity プロジェクトに Firebase を追加する](https://firebase.google.com/docs/unity/setup?hl=ja)を一通り読みましょう。
Firebaseの有名なことの1つが、公式ドキュメントが分かりやすくしかもローカライズされており至れり尽くせりです。
最悪何かのトラブルで機能が使えず開発が止まるようなことがあれば、[公式のサポート](https://firebase.google.com/support?hl=ja)がしっかり対応してくれるため使わないと損です。

把握したらFirebase Unity SDKのダウンロード
<img width="600" alt="スクリーンショット 2019-06-17 0.37.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/6de74fb4-5b6b-f5cb-2d75-04919631ad4d.png">
次にFirebaseプロジェクトを作成した後にコンソール上からFirebaseのUnityアプリを追加設定
<img width="600" alt="スクリーンショット 2019-06-17 0.40.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/dbe58a86-56c9-a13b-c125-00a6b79769b8.png">
といっても結局はiOS/Androidの設定が必須です。
これはFirebase Unity SDKがUnityのプラットフォームビルドでiOS/Androidにしかサポートしていないということです。
デスクトップにも対応していると公表していますが、あれは
<img width="600" alt="スクリーンショット 2019-06-17 0.43.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/68c8c24b-2e7d-c5ea-e693-c8bb6539ae16.png">
ここでダウンロードした.jsonファイルをUnityプロジェクトの中に入れておきましょう。
<img width="600" alt="スクリーンショット 2019-06-17 0.43.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/48631686-276c-4aa7-1a84-92195120e85d.png">
<img width="600" alt="スクリーンショット 2019-06-17 0.48.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/00b1ff2e-6b23-63d3-6314-81634d9f10d6.png">
Firebase Unity SDKダウンロード後、解凍して中身を見ると.NET 3.5と.NET 4.xに対応した.unitypackageが入ってありますが、.NET3.5を使うメリットはもう無いのでNET 4.x対応の方を取り込んでいきましょう。
<img width="600" alt="スクリーンショット 2019-06-17 0.59.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/f7afdbc9-3465-4f50-61e9-139ba690fae6.png">
<img width="400" alt="スクリーンショット 2019-06-17 0.55.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/9890a55b-4f3a-fafe-2c32-d7ae0a2840dd.png">
先ほどFirebaseプロジェクトにUnityアプリを作った際に設定したパッケージ名を**Bundle Identifier**に設定しておきましょう。
<img width="450" alt="スクリーンショット 2019-06-17 3.16.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/f933dd1c-ae0d-bb7a-2530-bf73b9ae3097.png">

さて、これで準備が整いました。

### 解説するFirebaseのサービスについて
今回は、**Auth**と**Storage**を解説していきます。

Authを選んだ理由は、各サービスで設定する[ルール](https://firebase.google.com/docs/rules?hl=ja)でユーザー情報が無いとサービスを利用できなくさせる設定がデフォルトにあり、**セキュリティ的にもユーザー情報がある前提で設計しておいた方がセキュア**なのですが、そのユーザーを作ったり管理できたりする機能がAuthに備わってあります。
そのため必ず最初に押さえておくべきサービスなのです。

Storageは、リソース管理に最適なツールです。
ルールの設定をユーザー情報がある前提に設定しておけば、Unity上でしかUpload/Downloadできないようになるためとてもセキュアでセキュリティ対策コストが低いアプリ開発ができちゃいます。
またStorageは、**URLでダウンロードできる設計になっているため、WWWやAssetBundleでリソースを取得することが可能**であるため最初の方で慣れておくサービスのもう一つです。

## Auth
Authは、いろんなサービスとの連携が可能であり、Web界隈でFirebaseが人気であるうちの1つです。
<img width="600" alt="スクリーンショット 2019-06-17 5.47.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/2c3529b1-1ca4-752c-2fa9-6fe1437b5f63.png">
<img width="600" alt="スクリーンショット 2019-06-17 2.31.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/bee1bec1-e79b-f729-99ba-062f863a01e0.png">
ところが、Unityで各サービスの連携を行うには、どうしても[ネイティブプラグイン](https://docs.unity3d.com/ja/current/Manual/NativePlugins.html)を作る必要が発生してしまいます。
例えば、[Twitter連携](https://firebase.google.com/docs/auth/unity/start?hl=ja)ですが、他の連携も同様に最初にアクセストークンなどを必要としており、その取得方法は、iOS/Androidのネイティブコードで解説されてあります。
<img width="600" alt="スクリーンショット 2019-06-17 3.56.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/eb9460cf-760e-4b4d-a0e4-da39fa98b730.png">
<img width="600" alt="スクリーンショット 2019-06-17 3.56.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/7af4545e-2b8f-4654-87db-7900fa54f54b.png">
<img width="600" alt="スクリーンショット 2019-06-17 3.57.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/4a92a729-ba50-4fee-9c06-80108bc27550.png">
開発するアプリがSNS連携必須でなければ特に関係ないことですが、必須となるとかなり工数がかかってしまいます。これは開発手法の話でもありますが、最初からSNS連携を対応するよりも、**まずは機能を扱えるようにして他に優先度の高い対応を進める**ために[パスワードでの認証](https://firebase.google.com/docs/auth/unity/password-auth?hl=ja)または[電話番号での認証](https://firebase.google.com/docs/auth/unity/phone-auth?hl=ja)で仮実装すると良いでしょう。

そのため今回は、[パスワードでの認証](https://firebase.google.com/docs/auth/unity/password-auth?hl=ja)で解説を進めていきます。
公式に最低限扱う機能をピックアップして、それらのソースコードを載せているためそのまま参考にしちゃいましょう。
<img width="600" alt="スクリーンショット 2019-06-17 3.57.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/1d52e1aa-2283-f8fe-3f19-124a3bb985a5.png">
次にFirebase コンソールのAuthenticationを開いて、ログイン方法から**メール/パスワードを有効**にしておきましょう。
<img width="600" alt="スクリーンショット 2019-06-17 2.32.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/185e474e-8156-a6ad-c5e6-60ce9bccdee7.png">

例えば、アプリ起動時にユーザー確認を処理する実装で、既存ユーザーだった場合は何もせずコンテンツを扱えうようにするが、nullでエラーの時はユーザー登録を完了しなければコンテンツが扱えないような設計を実装したとします。
<img width="600" alt="スクリーンショット 2019-06-17 4.20.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/037e915b-8126-2a93-0f37-384e06a53fde.png">
上記のようにエラー内容にどうしてエラーになったのか詳細が分かり、`ContinueWith`メソッドの引数`Task`で処理結果がどんなステータスなのか把握できるため、ステータス違いで別機能を実装することがとても容易です。
<a href="https://firebase.google.com/docs/reference/unity/class/firebase/auth/firebase-auth?hl=ja"><img width="600" alt="スクリーンショット 2019-06-17 6.00.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/4f434c9d-0f79-1ef0-08ca-70aaa5d040a8.png"></a>
また、パスワード認証でのAuthでは、メールアドレス毎でユーザー管理になるため同一メールアドレスで別アカウントを作ることはできません。ですが、ここでPRIMARY KEY扱いになっているメールアドレスは、`@`が入った文字列であればなんでも登録できちゃう設計になってあります。
<img width="450" alt="スクリーンショット 2019-06-17 4.29.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/a8c22a8c-4d23-d2ee-59f8-4203ae2e674b.png">
そのため、メールアドレスのフィールドに入れる文字列は、裏側で勝手に作るようにし（例えばその時のユーザーの総数+1を`@`の前に付けてサービスドメインをメールアドレスのドメインにするなど）、パスワードのフィールドは[UUID](https://docs.unity3d.com/ja/current/ScriptReference/SystemInfo-deviceUniqueIdentifier.html)を扱うよう設計すれば全て裏側で自動的にユーザーの登録と認証が可能です。

また、[Firebase Admin SDK](https://firebase.google.com/docs/admin/setup)を用いて[Functionsまたは独自のサーバーとFirebase Authenticationを連携させる](https://firebase.google.com/docs/auth/admin?hl=ja)ことで開発しやすくなるサポートが付いてきます。
その中でサードパーティ、外部サービスと連携できるようになる[カスタム 認証・トークン](https://firebase.google.com/docs/auth/admin/create-custom-tokens)の扱い方は、[GitHubにアップしている](https://github.com/gremito/firebase-game-app/blob/master/Assets/Scripts/firebase/FirebaseAuthManager.cs#L104)ので参考になれば幸いです。


## Storage

[AWSだとS3](https://aws.amazon.com/jp/s3/)にあたるサービスで、無料でこのクオリティはAWS以上ではないかなと思うくらいリソース管理に最適です。
<img width="600" alt="スクリーンショット 2019-06-17 5.48.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/0d1f5a1b-93d9-3690-391a-d7273a7d4947.png">
デフォルトで設定されているルールは、**Authで認証済みユーザーであれば使用可能**というセキュリティ設定ですが、開発中は一旦デフォルトで大丈夫です。どうしても心配になるようでしたら[公式のルールについてのガイド](https://firebase.google.com/docs/storage/security/user-security?hl=ja)を読むと良いでしょう。
<img width="600" alt="スクリーンショット 2019-06-17 6.33.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/44b0c33e-209f-b9ff-36d7-9ee66ca5ed49.png">
Storageのスタートガイドで解説されている[公開アクセスの設定](https://firebase.google.com/docs/storage/unity/start?hl=ja#set_up_public_access)にて書かれてありますが、とても分かりにくいですよね＾＾;
しかもAuthの実装が先に完了されていれば、`using Firebase;`で`Firebase.Auth.`や`Firebase.Storage.`など共通で扱う**Firebase**クラスがAuthの情報を持っているため、ルールのセキュリティ設定を気にすることなくStorageの実装ができるように設計されてあります。
<img width="600" alt="スクリーンショット 2019-06-17 16.18.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/6fcb89bb-5ab1-b88d-fe9b-6fd4f692707b.png">
リソースのアップロードやダウンロードは以下のように実装しますが、特に注目なのがURLでのダウンロード実装が自前で必要になります。要するに`Firebase.Storage`は、**ルールのセキュリティの対応と問題ない場合はアクセスしたリソースのURLを返す**実装になってあります（他にもこの中で色々やってそうですが知りたい場合は公式に問い合わせてみると良いかも）。
<img width="350" alt="スクリーンショット 2019-06-17 16.08.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/5388853d-396d-142c-8cd7-6f9aa844a26c.png"> <img width="350" alt="スクリーンショット 2019-06-17 16.08.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/2b3bf3a8-bb32-80ef-7a47-919ecbe807a5.png">
<img width="350" alt="スクリーンショット 2019-06-17 16.08.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/e045f3e9-8065-238b-8944-24a164c18709.png"> <img width="350" alt="スクリーンショット 2019-06-17 16.08.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/d0e4519e-3e83-11d8-791a-35958cdf7e00.png">
ですがこの実装で、セキュアなリソース管理ができ、大規模な開発でなければサーバを契約せずとも無料でリソースをFirebaseに管理することができるため、**AssetBundle**の実装もでき、Unityエンジニアとしては最高じゃないでしょうか笑
<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/72505cf2-9af2-8bee-3696-b68ffef37fc8.png"> <img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82601/8119ddaa-31fe-4fdb-73af-6e13b16fd7a5.png">
こちらもUNIBOOK10の執筆で一部書いた内容でした。
ですが、Unity 2018.2以降から**Addressable Asset System**が登場してきたため、次回は**Cloud StorageとAddressable Asset Systemでリソース管理**に関する執筆または記事作りをやろうかなと考えておりますー！

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/unitetokyo2018?src=hash&amp;ref_src=twsrc%5Etfw">#unitetokyo2018</a> 講演情報<br>そろそろ楽がしたい！新アセットバンドルワークフロー&amp;リソースマネージャー詳細解説<br> <br>大前 広樹（UTJ｜日本担当ディレクター）<br><br>イベントの公式情報はこちら<a href="https://t.co/alUH8IDAkq">https://t.co/alUH8IDAkq</a> <a href="https://t.co/Xs61eL1Vx7">pic.twitter.com/Xs61eL1Vx7</a></p>&mdash; ユニティ・テクノロジーズ・ジャパン (@unity_japan) <a href="https://twitter.com/unity_japan/status/992350625311674368?ref_src=twsrc%5Etfw">2018年5月4日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## さいごに
おそらく最初に読んでもらった[Unity プロジェクトに Firebase を追加する](https://firebase.google.com/docs/unity/setup/?hl=ja)のステップ2に『Firebase プロジェクトの詳細については、[Firebase プロジェクトについて理解する](https://firebase.google.com/docs/projects/learn-more?hl=ja)をご覧ください。』と書かれており、初めて触る人にとっては全て理解してすぐに扱えるようになることなんて早々ないと思います。

Firebaseを使い慣れたい方は、すでに誰かがやっていることと同じことを実際にやってみて覚えていくと良いでしょう。
また、[FJUG（Firebase Japan User Group）](https://firebase.asia/)というコミュニティがあるので、FJUGのSlackに入って情報交換などすると良いでしょう。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://t.co/fnGN5Q8gJX">https://t.co/fnGN5Q8gJX</a> slack の参加のURLです。 <a href="https://twitter.com/hashtag/FJUG?src=hash&amp;ref_src=twsrc%5Etfw">#FJUG</a></p>&mdash; コキチーズ🔥続編開発中 (@k2wanko) <a href="https://twitter.com/k2wanko/status/1111215740873404418?ref_src=twsrc%5Etfw">2019年3月28日</a></blockquote>
逆にUnityをもっと扱えるようになるためには、Unityはゲーム・ビジュアルコンテンツ・ツールアプリなど色々作れちゃうので機能がとても豊富です。そのため、日々Unityでもの作りをするととても良いです。
例えば、[1WeekGameJam](https://unityroom.com/)というネット上のイベントや [@KzoNag](https://twitter.com/KzoNag)さんが主催している[ゆにくえ福岡](https://unique-fukuoka.connpass.com/)に参加するなどして経験値を貯めていきましょう！
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【RT希望🙌】一週間でゲームを作るイベント <a href="https://twitter.com/hashtag/unity1week?src=hash&amp;ref_src=twsrc%5Etfw">#unity1week</a> <br>次回は 7月1日(月) に開催します。<br>作品の品質は問いませんのでどなたでも気軽に参加ください〜。<br>ルールや過去作品はリンク先でご確認ください！<a href="https://t.co/2uhr9rdqDr">https://t.co/2uhr9rdqDr</a></p>&mdash; naichi (@naichilab) <a href="https://twitter.com/naichilab/status/1137322106067140609?ref_src=twsrc%5Etfw">2019年6月8日</a></blockquote><blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">今週もゆるっとやります<br>ゆにくえ福岡 ~ Unity Question Space Fukuoka ~ #50 <a href="https://t.co/TOifG1VOEv">https://t.co/TOifG1VOEv</a> <a href="https://twitter.com/hashtag/%E3%82%86%E3%81%AB%E3%81%8F%E3%81%88%E7%A6%8F%E5%B2%A1?src=hash&amp;ref_src=twsrc%5Etfw">#ゆにくえ福岡</a></p>&mdash; ながみね (@KzoNag) <a href="https://twitter.com/KzoNag/status/1138005048401678336?ref_src=twsrc%5Etfw">2019年6月10日</a></blockquote>