Android
Kotlin
android開発
Firebase
FirebaseRealtimeDatabase

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

Firebase Realtime Databaseとは

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

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

準備

Firebaseと接続

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

Realtime Databaseを作成

スクリーンショット 2018-12-31 23.08.53.png
スクリーンショット 2018-12-31 23.08.59.png
とりあえずテストモードで
スクリーンショット 2018-12-31 23.09.16.png
これで箱ができた
スクリーンショット 2018-12-31 23.09.41.png

書き込みボタンをつくる

依存関係の追加

  implementation 'com.google.firebase:firebase-database:XX.X.X'

この一文をアプリレベルのbuild.gradleファイルに追記する
スクリーンショット 2018-12-31 23.14.10.png
スクリーンショット 2018-12-31 23.14.15.png
dependencies{}のなかね
バージョンはfirebase-coreと揃えるといい感じ

レイアウトファイルの作成

スクリーンショット 2018-12-31 23.22.20.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のインポート

import com.google.firebase.database.FirebaseDatabase

②共有インスタンス取得

val database = FirebaseDatabase.getInstance()

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

val ref = database.getReference("hogehoge")

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

ref.setValue("fugafuga")

ボタンを押すと

スクリーンショット 2018-12-31 23.22.37.png

hogehogeにfugafugaが作られた!

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

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

スクリーンショット 2018-12-31 23.34.32.png

読み込みボタンを作る

レイアウトファイル

ボタンをもう一個追加
スクリーンショット 2018-12-31 23.46.06.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()
                }
            })
        }
    }
}

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

            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っていうメソッドをオーバーライドしてあげないといけないみたい
データが書き換わった時に備えてリスナーになってるのかな?

val value = dataSnapshot.getValue(String::class.java)

ここでrefの中の値を取ってきてる
中身はトーストで出してみた。

ボタンを押すと

データベースがこんな感じだと
スクリーンショット 2018-12-31 23.49.34.png
fugafugaがトーストされる!
スクリーンショット 2018-12-31 23.49.08.png

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