CloudFirestoreの簡単な使い方(Android)

##はじめに
CloudFirestoreのAndroidでの基本的な使い方をメモ。
(導入から簡単なデータの送信受信など。)
使用言語はJava、開発環境はAndroidStudioを使用しています。
初投稿なので見にくい点が多々あると思いますがご了承を。
##Firestoreについて
FirestoreはNoSQLデータベースです。
ファイル構造は画像の通りです。
コレクション内にドキュメントが入っていてその中のデータを使います。
ドキュメント内にサブコレクションを作成することも可能です。
![structure-data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686889/4a5dbf95-be00-ebfc-36e7-4f1fb87593b2.png)

##プロジェクトの作成、準備
[Firebase](https://console.firebase.google.com/u/2/)のホームページからプロジェクトを作成をクリックし、プロジェクトの追加をクリック好きな名前を設定しアナリティクスは有効、アカウントを選びプロジェクトを作成。
アプリは今回はAndroidなのでAndroidを選択。
###Android アプリに Firebase を追加
**手順1 アプリの登録**
ここでの入力はAndroidパッケージのみで大丈夫です。
必要な場合はニックネームやSHA-1を記入。(今回は入力なし)
**手順2 設定ファイルのダウンロード**
google-services.jsonをダウンロードし
左上の表示方法をProjectに切り替えappにjsonファイルを導入
サイトの右の画像と同じ場所にjsonファイルが存在しているならOK
**手順3 Firebase SDKの追加**
サイトに表記されている内容をビルドグレイドルに追加。
サイトに表記されている内容とは別に以下の内容をアプリレベルのグレイドルに追加。

```gradle:app
dependencies {
implementation 'com.google.firebase:firebase-core:17.0.0'
implementation 'com.google.firebase:firebase-firestore:20.0.0'
}
```

バージョンは[このサイト](https://firebase.google.com/docs/android/setup?hl=ja)下の方の使用可能なライブラリから最新のものを調べて表記。


**手順4 アプリを実行してインストールを確認**
ここは終わらない場合があるためスキップで大丈夫です。
確認はアプリを実行し、logcatで***I/FirebaseInitProvider: FirebaseApp initialization successful***が表示されていれば完了しています。
**手順5 firestoreの作成**
サイト左側タブのCloud Firestoreをクリックしてデータベースの作成
ルールは今回は本番環境モードを選択。
(テストモードは30日更新しないとアクセス拒否になります)
ロケーションは適当な場所を選びます。
そのままだとルールが厳しいため
***write: if falseをwrite: if true***に変更します
![53c13ab8b30c6ebcc4556a9541a4f954.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686889/fd49e53e-c5a0-a764-ca13-23cf955f1c35.png)
以上で準備は完了です。
#コード
送信・受信と他使えそうなコードを少し記述します。
Firestoreを確認しながら実行してみてください。
##ドキュメントとコレクションの指定
以下の文で指定することができます。
指定したドキュメント/コレクションが存在しない場合データを保存する時に作成されます。

```java

DocumentReference mDocRef = FirebaseFirestore.getInstance().document("コレクション名/ドキュメント名");
```
##送信
まず初めに送信の処理のコードを紹介します。
###Mapの保存

```java

Map<String, Object> data = new HashMap<>();
       data.put("A","りんご");
       data.put("B","みかん");
       data.put("C","ぶどう");
        mDocRef.set(data);
```
###リストの保存
```java

ArrayList<String> group = new ArrayList<>();
        group.add("りんご");
        group.add("みかん");
        group.add("ぶどう");
        Map<String, Object> data = new HashMap<>();
        data.put("フィールド名",group);
        mDocRef.set(data);
```
##受信
次にFirebaseの値を取得するときのコードを紹介します
###Mapの取得
```java

mDocRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                       //値が取得できた時の処理
                        String save = (String) document.get("フィールド名");//
                    } else {
                        //値が存在しなかった時の処理
                } else {
                    //取得に失敗した時の処理
                }

            }
        });
```
###リストの取得
```java

mDocRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                       //値が取得できた時の処理
                       ArrayList<String> group =  (ArrayList<String>) document.get("フィールド名");
                    } else {
                       //値が存在しなかった時の処理
                    }
                } else {
                    //値の取得に失敗した時の処理
                }

            }
        });
```
##他によく使いそうなコード
次に使いそうなコードを記述します。
###保存が成功・失敗した時の処理
データを送信する処理の後に記述します。

```java

mDocRef.set(data).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    /// 保存が成功した時の処理
                } else {
                    /// 保存が失敗した時の処理
                }
            }
        });
```
###値が変更された時の処理
起動時と値が変更された時に実行されます

```java

mDocRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
                    @Override
                    public void onEvent(@Nullable DocumentSnapshot snapshot,
                                        @Nullable FirebaseFirestoreException e) {

                        if (snapshot != null && snapshot.exists()) {
                            Log.d("TAG", "Current data: " + snapshot.getData());
                            //変更されたときの処理
                        }
                    }
        });
```
##さいごに
以上でFirestoreの使い方の紹介を終わります。
ありがとうございました。