본문 바로가기

TIL

[TIL] Kotlin Firebase - Realtime Database [ 1 ] Data 저장하기

Topic =  Firebase의 Realtime DB를 사용해서 Data를 저장하고, 저장된 Data를 불러오기

 

 


 

Realtime Database

 

클라우드서버 참조 이미지 출처 :  https://firebase.google.com/products/realtime-database?hl=ko

Database

   앱 개발에 있어서 Database는 사용자 정보, 콘텐츠 등 다양한 데이터를 저장하고 관리하기 위해 필요한 요소이다. Local  DB는 앱 설정과 같이 중앙 데이터에서 저장할 필요가 없거나, Data의 일부를 캐싱하는 것과 오프라인 모드를 지원할 때 사용되어지고, 서버 DB는 사용자의 정보, 콘텐츠 등 다양한 데이터를 서버 DB, 즉 중앙 데이터에서 저장하고 관리하여 사용자로 하여금 데이터의 동시성을 제공하며 이로인해 사용자간의 실시간 상호작용이 가능토록 한다.

 

Realtiem DB

   로컬 DB만으로 게시글이나 채팅 등과 같이 다른 사용자의 Data에 읽기, 쓰기와 같은 접근을 할 수 없어 다른 사용자의 Data에 접근하도록 해서 사용자 사이의 상호작용을 가능토록 하기 위해선 서버를 구축해 Data를 서버에 저장하고, 사용자들이 Data를 통해서 정보를 받아 상호작용이 가능하도록 해야한다. Firebase를 사용하면 별도로 개발자가 서버를 구축할 필요가 없이 Firebase에서 제공하는 클라우드 서버에 호스팅해서 Firebase 콘솔을 통해 Data를 관리할 수 있다.

 

Realtime DB의 특징

  • Data 저장 형식 - JSON
  • 데이터 계층 구도 - 트리 계층 구도
    • 코드에서 계속 나올 Child가 트리 계층 구도에서 Child Node를 뜻한다 ( Node.js 의 노드가 이 노드구나 )
  • 실시간 동기화 
    • HTTP 요청 방식이 아닌 동기화 방식으로 통신되며, 데이터가 변경될 때 연결된 모든 기기가 동기화를 진행하여 업데이트 하는 방식의 구조이다.
  • NoSQL - 비관계형 SQL (  NotOnly SQL )
  • Firebase SDK를 통한 멀티 플랫폼 통합 호환 지원
  • Firebase SDK를 사용해 Database와 상호 작용
    • 일반적인 서버 DB의 경우 데이터 호출 메서드를 서버에서 관리하여 API EndPoint, Routing 등의 방식을 사용하는데,  Firebase의 경우 Firebase SDK 및 API를 사용하여 데이터 호출 메서드를 관리한다. Firebase SDK를 사용하는 경우 앱에서 DB에 접근하고 데이터 호출 메서드를 작성 및 실행한다.
    • Firebase SDK는 아래와 같이 클라이언트 SDK에서 제공하는 메서드를 말한다.
firebase.child("users").child(userName).get().addOnSuccessListener {
    var value = it.value
    ...
}.addOnFailureListener{
    val message = it.message
    val errorCode = it.code
    ...
}

 

 

Realtime DB 사용 예제

build.gradle
dependencies {
   // BoM 플랫폼 을 통한 버전 관리
  implementation platform "com.google.firebase:firebase-bom:32.3.1"
  implementation "com.google.firebase:firebase-auth"
  implementation "com.google.firebase:firebase-firestore"
}

 

 

MainActivity.kt
private val db : FirebaseDatabase
   // 이후 onCreate 또는 ViewModel 내부에서 아래의 함수로 초기화
   db = Firebase.database
   
// or
private val db : Firebase.database
  • Firebase Database를 선언 및 초기화 하는 여러가지 방법 중 일반적으로 사용하는 두가지의 방법이 있는데 db : FirebaseDatabase 타입으로 선언할 경우,  onCreate 내부또는 ViewModel의 내부에서 초기화를 추가로 해주어야 한다 두 접근 방식에서의 결정은 Activity / Fragment의 수명 주기 동안 참조를 다시 할당해야 할 경우가 있을 수 있는 경우 첫번째 코드로, 아닐 경우 두번째 코드를 사용하면 될 것 같다.
  • Google에서 제공하는 Firebase 코드에서는 변수 선언과 초기화를 분리하여 작성하는 것으로 별도로 문제가 생기지 않으면 번거롭더라도 변수 선언과 초기화를 분리하여 작성하도록 하자.

 

private val messageRef = db.getReference("messages")
// 위에 코드 또는 onCreate 내부에서 아래 코드 작성
val messageRef = db.reference.child("messages")
  • 위에 두가지 코드도 동일한 결과를 얻는 코드이지만 조금 상이한 부분이 있다 앞에서 먼저 db 관련해서 다룬 코드와 비슷한 형태기 때문에 해당 코드도 Google에서 권장하는 db.reference.child()를 통해서 구현할 수 있도록 하자.
  • Firebase SDK로 인해 get, set이 강제되지 않는 상황에서 kotlin은 get 사용을 최소화 하는 느낌이다. java와의 차이를 두기 위해서 인 것 같은데 나중에 프로젝트가 끝나고 조금 여유가 생기면 이런 알쓸신잡 내용들에 대해서 파봐야 겠다.

 

 

Manin Activity 코드 작성에 앞서 Data class를 정의하여 DB에 넣을 데이터 형식을 지정해준다.

data class AppMessages (
   val name : String? = null
   val text : String? = null
)

 

MainActivity 작성 코드 - DB 저장하기

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var manager: LinearLayoutManager

    private lateinit var db: FirebaseDatabase
    private lateinit var adapter: AppMessageAdapter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // Realtime DB 초기화
        db = Firebase.database
        
        // 데이터가 저장 될 node를 지정해준다
        val messagesRef = db.reference.child(MESSAGES_CHILD)
        
        // Send Btn 클릭 시 Text,Writer Data를 DB에 저장
        binding.sendButton.setOnClickListener {
            val appMessages = AppMessages(
                binding.messageEditText.text.toString(),
                binding.messageWriterText.text.toString()
            )

            db.reference.child(MESSAGES_CHILD).push().setValue(appMessages)
            binding.messageEditText.text.clear()
        }
    }

    companion object {
        const val MESSAGES_CHILD = "messages"
    }
}

 

저장된 데이터 가져오기

 

   데이터를 읽는 방식은 addValueEvenetListener를 override하여 데이터의 변화가 감지되었을 때 콜백을 받아 해당하는 노드에 데이터를 가져오는 방식으로도 구현할 수 있으며 ( 채팅, SNS 게시글 등에 적합 ) 특정 조건을 만족하는 데이터만 가져오기 위해 Query를 사용해서 데이터를 가져올 수 있다 Listener, Query 를 사용해 데이터를 가져오는 기능을 게시글에 추가하면. 링크 추가예정.

 

➕ Listener로 DB Data 불러오기

 

[TIL] Kotlin Firebase - Realtime Database [ 2 ] 저장된 데이터Listener로 가져오기

Topic = Firebase Realtime DB에 저장된 데이터를 여러가지 방식으로 가져오는 방법 학습 Why - DB를 가져오기 위해 사용하는 Listener에 대해서 학습해보고 차이점을 확인하기 Realtime DB의 데이터를 가져올

junes-daily.tistory.com

 

 

데이터 삭제

 

   DB의 데이터를 삭제할 땐 removeValue 명령어를 사용하거나, setValue의 값을 null로 변경해주는 방법이 있는데 removeValue() 메서드를 사용하는 것이 데이터 삭제의 목적을 명확하게 드러내어 코드의 가독성을 높일 수 있기 때문이다.

 

 

 


 

[ A. 오늘 복습한 내용 / B. 다음에 학습할 내용 ]

A. 개념학습과 기능 학습에 바빠서 복습한 내용 특별히 없는 것 같다

 

B. Kotlin에서 Get, Set~ 함수 사용을 최소화 하려는 이유

 

B. 전역변수에서 초기화를 하는 것과 변수 선언과 초기화를 분리하는 것에 명확한 서열정리. 확실히 뭐가 어떤점 때문에 좋은지

 


 

[오류,에러 등등]

1. 코드 스타일이 다 달라서 왜 서로 다른지에 대해서 의문이 생겨서 되게 작은 부분에 많은 시간을 보낸 것 같아서 좀 아쉽다.

 

 

 

 


 

[느낀 점]

1. 일정 시간을 정해놓고 이해하지 못했다면 메모해두고 시간을 갖고 난 뒤 다시 한번 시도해보는 것이 좋겠다.

 

2. 앉아있는 시간은 많은데 학습한 내용은 적은 느낌.

 

3. 블로그 글 참조해서 학습 하는데 내 상황이랑 똑같은 광고가 나와서 놀랬다 ↓

지금 내 상황

 

 


[Reference]

 

// Routing

https://ko.wikipedia.org/wiki/%EB%9D%BC%EC%9A%B0%ED%8C%85

 

// Realtime DB

https://firebase.google.com/docs/database?hl=ko

https://cionman.tistory.com/72

https://tekken5953.tistory.com/entry/Firebase-Realtime-Database-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0