初心者がKotlinでFirebase Realtime Databaseを使ってみた

#Firebase Realtime Databaseとは
本格的なアプリを作ろうと思ったらデータベースって必要だよね。
Firebaseさんはそれも提供してくれるなんて粋だねえ。

OracleとかMySQLとかとちょっと違うのは
リレーショナルデータベースでないこと
アプリでの使用に特化していることなんだって。

#準備
##Firebaseと接続
こちらを参考にアプリとFirebaseを接続しよう
https://qiita.com/Natsuki_on_Rails/items/38cfcf6829e282b6f63e

##Realtime Databaseを作成
<img width="249" alt="スクリーンショット 2018-12-31 23.08.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/48637d9f-416b-4ba1-57d9-d01373e0db3e.png">
<img width="979" alt="スクリーンショット 2018-12-31 23.08.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/1f2645d4-78a1-d13b-9697-6459dd79715e.png">
とりあえずテストモードで
<img width="701" alt="スクリーンショット 2018-12-31 23.09.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/183c7a91-ac4a-6df5-b8fb-793624fc5ef3.png">
これで箱ができた
<img width="1069" alt="スクリーンショット 2018-12-31 23.09.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/ec3f008a-de7b-dcf0-9f55-712087ed1af6.png">

##書き込みボタンをつくる
###依存関係の追加

```kotlin
  implementation 'com.google.firebase:firebase-database:XX.X.X'
```
この一文をアプリレベルのbuild.gradleファイルに追記する
<img width="331" alt="スクリーンショット 2018-12-31 23.14.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/8404c605-49af-da2a-6c55-a6956c8c9ade.png">
<img width="645" alt="スクリーンショット 2018-12-31 23.14.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/4110817c-5fb5-0256-817d-e9a5b8b237ed.png">
dependencies{}のなかね
バージョンはfirebase-coreと揃えるといい感じ

###レイアウトファイルの作成
<img width="286" alt="スクリーンショット 2018-12-31 23.22.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/741e3a8b-d954-8fde-cc73-bbd09b39d093.png">
ただボタンおいただけ

```main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <Button
            android:text="@string/write"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/writeButton" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="148dp"
            app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="231dp"/>
</android.support.constraint.ConstraintLayout>
```

###アクティビティの実装

```MainActivity.kt
package com.test.test

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import com.google.firebase.database.FirebaseDatabase


class MainActivity : AppCompatActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val database = FirebaseDatabase.getInstance()
        val ref = database.getReference("hogehoge")
        val buttonWrite = findViewById<Button>(R.id.writeButton)

        buttonWrite.setOnClickListener {
            ref.setValue("fugafuga")
        }
    }
}
```

①FirebaseDatabaseのインポート

```kotlin
import com.google.firebase.database.FirebaseDatabase
```

②共有インスタンス取得

```kotlin
val database = FirebaseDatabase.getInstance()
```

③hogehogeへのリファレンスの取得

```kotlin
val ref = database.getReference("hogehoge")
```

④ボタン押下時にhogehogeへfugafugaをセット

```kotlin
ref.setValue("fugafuga")
```

###ボタンを押すと
<img width="963" alt="スクリーンショット 2018-12-31 23.22.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/6c469ba1-760a-3485-4626-6beb84606aab.png">

hogehogeにfugafugaが作られた！

ちなみにこんな感じに書くとどんどんネストできる

```kotlin
ref.child("fugafuga").setValue("hagehage")
```

<img width="969" alt="スクリーンショット 2018-12-31 23.34.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/9976a1eb-47b3-f8cb-b5d7-4faf9933a9d4.png">

##読み込みボタンを作る
###レイアウトファイル
ボタンをもう一個追加
<img width="283" alt="スクリーンショット 2018-12-31 23.46.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/780871b9-795e-08c0-356e-b0188e913a6d.png">

```main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <Button
            android:text="@string/write"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/writeButton" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginStart="84dp"
            app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="228dp"/>
    <Button
            android:text="@string/read"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/readButton"
            android:layout_marginEnd="78dp"
            app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"
            android:layout_marginTop="228dp"/>
</android.support.constraint.ConstraintLayout>
```

###アクティビティファイル

```MainActivity.kt
package com.test.test

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ValueEventListener


class MainActivity : AppCompatActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        val database = FirebaseDatabase.getInstance()
        val ref = database.getReference("hogehoge")
        val buttonWrite = findViewById<Button>(R.id.writeButton)
        val buttonRead = findViewById<Button>(R.id.readButton)

        buttonWrite.setOnClickListener {
            ref.setValue("fugafuga")
        }
        
        //追加↓
        buttonRead.setOnClickListener {
            ref.addValueEventListener(object : ValueEventListener {
                override fun onDataChange(dataSnapshot: DataSnapshot) {
                    val value = dataSnapshot.getValue(String::class.java)
                    Toast.makeText(baseContext, value,
                        Toast.LENGTH_LONG).show()
                }
                override fun onCancelled(error: DatabaseError) {
                    Toast.makeText(baseContext, "読み込み失敗",
                        Toast.LENGTH_LONG).show()
                }
            })
        }
    }
}
```

データベースからの読み込みの場合は書き込みの時ほど簡単には書けないっぽい

```kotlin
            ref.addValueEventListener(object : ValueEventListener {
                override fun onDataChange(dataSnapshot: DataSnapshot) {
                    val value = dataSnapshot.getValue(String::class.java)
                    Toast.makeText(baseContext, value,
                        Toast.LENGTH_LONG).show()
                }
                override fun onCancelled(error: DatabaseError) {
                    Toast.makeText(baseContext, "読み込み失敗",
                        Toast.LENGTH_LONG).show()
                }
            })
```

onDataChangeとonCancelledっていうメソッドをオーバーライドしてあげないといけないみたい
データが書き換わった時に備えてリスナーになってるのかな？

```kotlin
val value = dataSnapshot.getValue(String::class.java)
```
ここでrefの中の値を取ってきてる
中身はトーストで出してみた。

###ボタンを押すと
データベースがこんな感じだと
<img width="977" alt="スクリーンショット 2018-12-31 23.49.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/bc6a830c-66b8-9b54-e6ae-3b093d9aca85.png">
fugafugaがトーストされる！
<img width="140" alt="スクリーンショット 2018-12-31 23.49.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/96104e0f-69ea-4910-02fe-5616f7d89659.png">

リレーショナルデータベースと違うからそっち知ってると戸惑っちゃうね。