📱 안드로이드 Android ~ Kotlin

[Android/kotlin] 구글 Firebase Realtime Database 사용하기

핑크빛연어 2022. 6. 10. 09:50

 

 

Realtime Database

 

Firebase의 Realtime Database는 NoSQL기반 cloud-hosted database입니다. 실시간으로 모든 클라이언트에서 데이터가 동기화 되어 사용할 수 있습니다.

 

 

https://firebase.google.com/docs/database/android/start

 

Android에서 설치 및 설정  |  Firebase Documentation

Check out what’s new from Firebase at Google I/O 2022. Learn more 의견 보내기 Android에서 설치 및 설정 Firebase에 앱 연결 아직 추가하지 않았다면 Android 프로젝트에 Firebase를 추가합니다. 데이터베이스 만들기 F

firebase.google.com

 

 

🚨 Realtime Database 생성

Firebase console 창에서 왼쪽 Realtime Database 를 클릭합니다.

 

데이터베이스 설정하는 창이 표시되는데요, 먼저 위치 설정을 해줍니다.

저는 실시간 데이터베이스 위치를 대한민국에서 가까운 싱가포르로 설정해주었습니다. 다음 버튼 클릭!

 

이제 실시간 데이터베이스 보안 규칙 설정 화면이 표시됩니다.
잠금 모드로 시작하게 되면 오직 인증된 사용자만 글을 읽고 쓸 수 있고, 테스트 모드는 모두가 사용할 수 있습니다.

보안규칙은 초기 설정 후에도 변경 가능하다고 합니다.
저는 아직 개발 단계로 테스트 모드로 시작하였습니다. 사용 설정 클릭~

 

(안드로이드 스튜디오에서도 Tools > Firebase 으로 들어가서 생성할 수 있습니다.)

 

 

🚨 소스코드 구성하기

 

앱 화면

send 버튼 클릭 시 edittext 에서 입력한 값이 회색 텍스트박스에 append 되고 데이터베이스에 wirte 됩니다.

 

 

1. build.gradle(:app)

◾ 앱에 실시간 데이터베이스 SDK 추가

   - dependencies 안에 Firebase database 에 대한 의존성을 추가해줍니다.

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'com.google.gms.google-services'
}

...

dependencies {
    ...
    implementation platform('com.google.firebase:firebase-bom:30.0.1')  // Import the BoM for the Firebase platform
    implementation 'com.google.firebase:firebase-database-ktx'  // Declare the dependency for the Realtime Database library
    ...
}

 

 

2. RealMainActivity.kt

 

◾ 데이터베이스에 쓰기

// Write a message to the database
val database = Firebase.database("https://....firebasedatabase.app")
val myRef = database.getReference("message")
myRef.setValue(binding.etInput.text.toString())  // 데이터 1개가 계속 수정되는 방식
myRef.push().setValue(binding.etInput.text.toString())  // 데이터가 계속 쌓이는 방식

myRef.setValue ("hi")

 

◾ 데이터베이스에서 읽기

실시간으로 앱 데이터를 읽기 위해 myRef 에 ValueEventListener 를 추가합니다.
이 클래스의 onDataChange() 메서드는 데이터가 변경될 때마다 호출됩니다.
이 클래스의 onCancelled() 메서드는 데이터 읽기에 실패 시 호출됩니다.

// Read from the database
myRef.addValueEventListener(object : ValueEventListener {
   override fun onDataChange(dataSnapshot: DataSnapshot) {  // Called once with the initial value and again
      val value = dataSnapshot.getValue<String>()
      Log.d(TAG, "Value is: $value")
   }
   override fun onCancelled(error: DatabaseError) {  // Failed to read value
      Log.w(TAG, "Failed to read value.", error.toException())  
   }
})

package com.eun.myappkotlin02.realtime

import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.eun.myappkotlin02.LogUtil
import com.eun.myappkotlin02.databinding.ActivityRealMainBinding
import com.eun.myappkotlin02.realtime.chat.view.ChatMainActivity
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.ValueEventListener
import com.google.firebase.database.ktx.database
import com.google.firebase.database.ktx.getValue
import com.google.firebase.ktx.Firebase

class RealMainActivity: AppCompatActivity() {

    companion object {
        const val TAG = "RealMainActivity"
    }

    lateinit var binding: ActivityRealMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityRealMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        initView()
    }
    
    
    private fun initView() {
        binding.btnSend.setOnClickListener {

            binding.tvText.append("\n")
            binding.tvText.append(binding.etInput.text)

            // [START write_message]
            // Write a message to the database
            val database = Firebase.database("https://....firebasedatabase.app")
            val myRef = database.getReference("message")

            myRef.setValue(binding.etInput.text.toString())  // 데이터 1개가 계속 수정되는 방식
//            myRef.push().setValue(binding.etInput.text.toString())  // 데이터가 계속 쌓이는 방식
            // [END write_message]

            Log.d(TAG, "myRef :: $myRef")
            binding.etInput.text.clear()

            // [START read_message]
            // Read from the database
            myRef.addValueEventListener(object : ValueEventListener {
                override fun onDataChange(dataSnapshot: DataSnapshot) {
                    // This method is called once with the initial value and again
                    // whenever data at this location is updated.
                    val value = dataSnapshot.getValue<String>()
                    Log.d(TAG, "Value is: $value")
                }

                override fun onCancelled(error: DatabaseError) {
                    // Failed to read value
                    Log.w(TAG, "Failed to read value.", error.toException())
                }
            })
            // [END read_message]

        }
    }
}

 

 

3. activity_real_main.xml

RealMainActicity 에 대한 레이아웃입니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="20dp" >

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:padding="20dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:text="Text"
        android:textSize="18dp"
        android:textColor="@color/black"
        android:background="@color/grey_300"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/et_input"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
        
    <EditText
        android:id="@+id/et_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/btn_send" />

    <Button
        android:id="@+id/btn_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="send"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/et_input"
        app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

감사합니다 ^-^

728x90
반응형