【Firebase 入門】Authentication、Realtime Database、 Cloud Storage とは

タイトルの 各Firebaseプロダクトの概要とチュートリアルを通しての実際の実装利用方法

# Firebase Authentication とは
Firebase Authentication では、パスワード、電話番号、一般的なフェデレーション ID プロバイダ（Google、Facebook、Twitter）などを使用した認証を行うことができます。また、OAuth 2.0 や OpenID Connect などの業界標準を使用しているため、カスタム バックエンドと簡単に統合できます。

## ユーザープロパティ
ユーザーが初めてアプリに登録するときに、利用可能な情報を使用してユーザーのプロフィール データ（一意の ID、メインのメールアドレス、名前、写真の URL から構成される基本プロパティ）が設定されます。

注: 認証されたユーザーは Firebase Realtime Database と Cloud Storage に対して、デフォルトでデータの読み取り、書き込みができます。

# Firebase Realtime Database とは
Firebase Realtime Database は NoSQL クラウドホスト型データベースです。データはすべてのクライアントにわたってリアルタイムで同期され、アプリがオフラインになっても引き続き使用できます。

注: 新しくプロジェクトを開始する場合、ほとんどのケースで Cloud Firestore のご利用をおすすめします。

## Firebase Realtime Database ルール
Firebase Realtime Database ルールでは、データベースへの読み取り / 書き込みアクセス権を持つユーザー、データが構造化される仕組み、存在するインデックスを決定します。

# Cloud Storage for Firebase とは
Cloud Storage for Firebase は、Google 規模で構築された、強力かつシンプルでコスト効果の高いオブジェクト ストレージ サービスです。写真や動画など、ユーザーが作成したコンテンツを保管、提供する必要のあるアプリ デベロッパー向けに構築されています。

デベロッパーは Cloud Storage 用の Firebase SDK を使用して、クライアントから直接ファイルのアップロードとダウンロードを行います。ネットワーク接続がよくない場合、クライアントは動作が停止したところから再試行できるため、ユーザーは時間と帯域幅を節約できます。

## Cloud Storage 用の Firebase Storage セキュリティ ルール
Cloud Storage 用の Firebase セキュリティ ルールは、Firebase Realtime Database ルール同様、わずか数行のコードで、Cloud Storage リクエストを特定のユーザーに限定する承認ルールや、アップロード サイズを制限する承認ルールを作成できます。加えて、ファイル名とパスの検証、`contentType` や `size` などのファイル メタデータのプロパティの検証といったデータ検証にも使用できます。

注: Cloud Storage はデフォルトの Google App Engine アプリと同じ Google Cloud Storage バケットを使用します。

# Cloud Functions で拡張する
これまで紹介した Firebase Authentication、Firebase Realtime Database、Cloud Storage for Firebase は、それぞれ Cloud Functions を利用することで機能を拡張することができます。一般的なユースケースは以下です。

- アプリでアカウントを作成したばかりのユーザーに登録完了の通知メールを送信
- 画像ファイルが Cloud Storage にアップロードされたときにサムネイルを生成する

重要: Cloud Storage バケットのロケーションと関数のロケーションとの距離によっては、ネットワーク レイテンシが大幅に増加する可能性があります。パフォーマンスを最適化するために、関数のロケーションは適切な場所に指定してください。

# Android アプリでFirebase Authentication、 Firebase Realtime Database、 Cloud Storage for Firebase を利用する
[Codelab](https://www.google.com/url?q=https://codelabs.developers.google.com/codelabs/firebase-android/%230&sa=D&ust=1599909316059000&usg=AOvVaw1EdWvH7de5CF1HvASk-XNs)とこちらの[サンプルコード](https://www.google.com/url?q=https://github.com/firebase/codelab-friendlychat-android&sa=D&ust=1599909316059000&usg=AOvVaw29U4LH7rf8JfsY869WaO6A)を参考にして、Firebase Authentication、Firebase Realtime Database、Cloud Storage for Firebase を試してみましょう。

## FirebaseプロジェクトとAndroidアプリの準備

### サンプルコードを入手する
GitHubからソースコードをローカル環境にクローンします。

```
$ git clone https://github.com/firebase/codelab-friendlychat-android
```

### Firebaseプロジェクトを作成する
次にサンプルアプリケーションをデプロイするために [Firebase プロジェクトを作成](https://firebase.google.com/docs/projects/learn-more?hl=ja#project-id)します。

### Android プロジェクトに Firebase を追加する
作成したFirebaseプロジェクトにクローンした[Androidアプリを追加](https://www.google.com/url?q=https://firebase.google.com/docs/android/setup&sa=D&ust=1599909316061000&usg=AOvVaw1m7herQvVoT2deqjqY1Y1k)します。

### デバッグ用の署名証明書 SHA-1 を追加する
Firebase Authentication を利用するために SHA-1 を追加します。SHA-1は以下のコマンドで発行。

```
$ keytool -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v -storepass android
```
![image7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351392/ea5a32d6-667f-8e1c-33b0-6ed5171030e9.png)

## Firebase Realtime Database ルールの設定

### 認証ユーザー に読み取りと書き込み権限を付与する
コンソールのエディターからルールを編集し、`公開` をクリックします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351392/478191e0-e3f4-2375-112e-87f8c0aeb532.png" width=90%>

## Authentication APIs の設定

### Google アカウントで認証できるように設定する
Sign-in method からログイン プロバイダとして Google を有効化し、`保存`をクリックします。

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351392/521d7a06-4d13-ea49-027f-e170d7a131c8.png)

### Dependency の追加とソースコードの編集
クローンしたプロジェクトをAndroid Studio で開き、[Enable Authentication](https://www.google.com/url?q=https://codelabs.developers.google.com/codelabs/firebase-android/?authuser%3D0%236&sa=D&ust=1599909316063000&usg=AOvVaw3iy43pPjOzEgSpdEEW-nRa) の **Add Firebase Auth dependency** 以降を参考に、

- app/build.gradle への dependency の追加
- 未承認ユーザーのサインイン画面への誘導
- サインイン画面での Sign-In with Google の実装

を行います。

適宜コンパイルエラーとなるので import class をすること。
![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351392/e6899501-c53a-d1e2-396f-07da66972af9.png)

Android emulator を起動します。Sign-In with Google の画面が確認できました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351392/6d40ad10-9fd9-e91c-a9be-f282e55b95bd.png" width=70%>

## Realtime Database にデータを追加
[Read Messages](https://www.google.com/url?q=https://codelabs.developers.google.com/codelabs/firebase-android/?authuser%3D0%237&sa=D&ust=1599909316063000&usg=AOvVaw1Z4O38RcE-maSBpoK3IYOh)  の **Import Messages** を参考にチャットで予め表示するメッセージを追加します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351392/b73eea91-b7b4-8361-fca5-06c5a2c9326b.png" width=80%>

### Dependency の追加とソースコードの編集
[Read Messages](https://www.google.com/url?q=https://codelabs.developers.google.com/codelabs/firebase-android/?authuser%3D0%237&sa=D&ust=1599909316064000&usg=AOvVaw2bvTnMDvSbjVrv7bhy_yN4)  の **Import Messages** 以降を参考に、

- app/build.gradle への dependency の追加
- メッセージの同期の実装

1. Firebaseリアルタイムデータベースを初期化し、データへの変更を処理するためのリスナーを追加
2. RecyclerView アダプタを更新して、新しいメッセージを表示
3. データベースのインスタンス変数を MainActivity クラスの他の Firebase インスタンス変数に追加

を行います。

Google アカウントで Sign-In に成功すると、先ほど Realtime Database に追加したメッセージが表示されました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351392/82c8840b-d6c4-13f4-27fe-97d44bab3e7b.png" width=80%>

## テキストメッセージ送信を実装
[Send Messages](https://www.google.com/url?q=https://codelabs.developers.google.com/codelabs/firebase-android/?authuser%3D0%238&sa=D&ust=1599909316065000&usg=AOvVaw2R4mbFxCqH7VeWtimNHLVL)  の **Implement text message sending** を参考にテキストメッセージ送信機能を実装します。ここで生成されるメッセージIDはリストの最後に追加されるようにシークエンシャルです。

## 画像メッセージ送信を実装
[Send Messages](https://www.google.com/url?q=https://codelabs.developers.google.com/codelabs/firebase-android/?authuser%3D0%238&sa=D&ust=1599909316065000&usg=AOvVaw2R4mbFxCqH7VeWtimNHLVL)  の **Implement image message sending** を参考にテキストメッセージ送信機能を実装します。

- 画像を選択
- ハンドル画像選択
- RTDB（リアルタイムデータベース）に一時的な画像メッセージを書き込む
- 選択した画像のアップロードを開始
- アップロードが完了したら、画像メッセージのURLをアップロードされた画像のものに更新

“ + “ ボタンをクリックすることで、テキスト / 画像を送信できるようになりました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351392/f459dd6d-7192-4699-6c63-f08307b44588.png" width=80%>