Android Studio

[Android][Firebase][Kotlin]데이터 읽기 관련 메소드

코린이탈출기 2022. 9. 9. 16:23
728x90

1. Realtime Database에서 데이터 읽기

 

1.1. 영구 리스너로 데이터 읽기, addValueEventListener() 메소드

  • 경로 전체 내용에 대한 변경 사항을 읽고 수신 대기한다.
  • onDataChange() 메소드를 사용하여 이벤트 당시에 존재했던 콘텐츠의 정적 스냅샷을 읽을 수 있다. 이 메소드는 리스너가 연결될 때 한 번 트리거되고 DB 데이터가 변경될 때마다 다시 트리거된다.
  • 변경된 모든 데이터를 가져올 때 유용
 

1.2. 리스너를 사용하여 한 번 읽기, addListenerForSingleValueEvent() 메소드

  • 한 번만 호출되고 즉시 삭제되는 콜백이 필요한 경우에 사용한다.
  • 한 번 로드된 후 자주 변경되지 않거나 능동적으로 수신 대기할 필요가 없는 데이터에 유용하다.
  • 이 메소드는 한 번 호출된 후 다시 호출되지 않는다.
예) 이후에 변경되지 않는 UI 요소를 초기화할 때, 새 게시물을 작성하기 시작할 때 이 메소드로 사용자의 프로필을 로드

 

 

* 예제: 고객이 매니저에게 작성한 후기 목록 가져오기

(사용 예시는 적절하지 않은 것 같기 때문에 코드 흐름만 참조할 것을 추천..)

 

1. 우선 데이터베이스에서 데이터를 읽기 위해 DatabaseReference를 선언한다.

 

// UserInfoConstants.REVIEWS = "reviews"
private val databaseReference = 
			FirebaseDatabase.getInstance().getReference(UserInfoConstants.REVIEWS)

 

 

2. 데이터의 변경 사항을 반영하기 위해 ValueEventListener() 메소드를 추가한다.

 

* ValueEventListener

데이터 변경이 발생하면 해당 리스너로 이벤트가 수신된다.

ValueEventListener에 대한 설명

 

 

3. 필요한 데이터를 참조할 자식 노드를 databaseReference에 이어 적어준다.

 

Realtime Database에 들어있는 데이터 구조

 

 

 

> 예제 코드

더보기
// 리뷰 uid 를 통해 리뷰 가져오기
private fun getReviewList(reviewUid: String) {

    databaseReference.child(reviewUid).child(UserInfoConstants.REVIEW_COMMENT)
        .addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {

                // 리스너에 전달된 변경된 데이터가 snapshot 에 들어온다.
                for( data in snapshot.children ) {

                    // snapshot 을 통해 받아온 data 들을 item 에 담아준다.
                    val item        = data.getValue<ReviewModel.Comment>()

                    // 필요한 데이터를 하나씩 가져온다.
                    val writerUid   = item?.uid.toString()
                    val userName    = item?.userName.toString()
                    val managerName = item?.managerName.toString()
                    val writingTime = item?.writingTime.toString()
                    val content     = item?.content.toString()
                    val commentUid  = data.key.toString()

                    reviewList.add(ReviewModel.Comment(
                        writerUid, userName, managerName, writingTime, content
                    ))

                    commentUidList.add(commentUid)
                }
            }

            override fun onCancelled(error: DatabaseError) {
            }
        })
}

 

 

1.3. 데이터 한 번 읽기, addChildEventListener() 메소드

  • 이 메소드는 데이터베이스의 특정한 노드에 대한 변경을 수신 대기하는데 유용하다.
  • 새로 변경된 데이터만 가져올 때 유용

 

* 예제: 채팅 목록 가져오기

 

 

 

> 예제 코드

더보기
// 채팅방 정보 가져오기
    private fun getRoomInfo() {
        databaseReference   .child(roomUid.toString())
                            .child(UserInfoConstants.CHAT_COMMENTS) // = "comments"
                            .limitToLast(1) // 마지막 메시지와 마지막 시간을 가져오기 위함
                            .addChildEventListener(object : ChildEventListener {
                                // 각 콜백의 DataSnapshot 을 통해 추가되거나 제거된 자식 데이터를 가져온다.
                                override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {

                                    val item = snapshot.getValue<ChatModel.Comment>()
                                    roomInfo.add(item!!)
                                }

                                override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
                                }

                                override fun onChildRemoved(snapshot: DataSnapshot) {
                                    roomList.clear()

                                    val item = snapshot.getValue<ChatModel>()
                                    roomList.add(item!!)
                                    notifyDataSetChanged()
                                }

                                override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {
                                }

                                override fun onCancelled(error: DatabaseError) {
                                }


                            })
    }

 

 

2. Firestore Database에서 데이터 읽기

 

2.1. get()을 사용하여 문서 가져오기

  • 메소드를 호출하여 데이터를 한 번 가져옵니다.
  • get 호출은 데이터베이스에서 최신 문서의 스냅샷을 가져온다.
  • addOnCompleteListener 또는 addOnSuccessListener를 사용하여 데이터를 읽어 올 수 있다. 둘의 차이점이 잘 정리된 블로그 참고는 "여기" 클릭

 

* 예제: 로그인한 사용자 정보 가져오기

 

1. instance를 선언한다.

 

 

2. "userInfo" 컬렉션에 저장된 사용자의 uid 중 현재 로그인한 사용자의 uid를 찾는다.

3. 일치하는 uid가 있을 경우, 해당 사용자의 정보를 가져온다.

 

 

 

 

> 예제 코드

더보기
private val db = FirebaseFirestore.getInstance()
private val uid = FirebaseAuth.getInstance().currentUser?.uid

// 사용자 정보 가져오기
fun getUserInfo(userName: TextView, userPhoneNum: TextView,
                petName: TextView, petAge: TextView, petWeight: TextView,
                petSpecies: TextView, petCharacter: TextView, context: Context) {

    db  .collection(UserInfoConstants.USER_INFO) // "userInfo"
        .get()
        .addOnCompleteListener { task ->
            if( task.isSuccessful ) {

                for( i in task.result!! ) {
                    // db에 일치하는 사용자 uid 가 있을 경우 정보를 가져온다.
                    if( i.id == uid.toString() ) {

                        // db 필드 데이터
                        val myName         = i.data[UserInfoConstants.USER_NAME]
                        val myPhoneNum     = i.data[UserInfoConstants.USER_PHONE_NUM]
                        val myPetName      = i.data[UserInfoConstants.PET_NAME]
                        val myPetAGE       = i.data[UserInfoConstants.PET_AGE]
                        val myPetWeight    = i.data[UserInfoConstants.PET_WEIGHT]
                        val myPetSpecies   = i.data[UserInfoConstants.PET_SPECIES]
                        val myPetCharacter = i.data[UserInfoConstants.PET_CHARACTER]

                        userName.text     = myName.toString()
                        userPhoneNum.text = myPhoneNum.toString()
                        petName.text      = myPetName.toString()
                        petAge.text       = myPetAGE.toString()
                        petWeight.text    = myPetWeight.toString()
                        petSpecies.text   = myPetSpecies.toString()
                        petCharacter.text = myPetCharacter.toString()

                        PreferenceManager().setString(
                            context,
                            UserInfoConstants.USER_NAME,
                            myName.toString()
                        )

                        break
                    }
                }
            } else
                println("No such document")
        }
        .addOnFailureListener { e ->
            println("실패 >> ${e.message}")
        }
}

 

 

2.2. 실시간 업데이트 받기, addSnapshotLisener() 메소드

 

* 예제: 사용자가 달력에서 선택한 날짜의 일정 가져오기

또는 선택한 날짜의 일정이 추가 및 수정 되었을 경우 업데이트 하기

 

1. instance 를 선언한다.

 

 

2. 일정 목록 가져오기

 

 

 

> 예제 코드

더보기
// 일정 목록
fun getScheduleList(year: Int, month: Int, day: Int) {

    db  .collection(ScheduleConstants.USER_SCHEDULE)
        .document(uid.toString())
        .collection(year.toString())
        .document(month.toString())
        .collection(day.toString())
        .addSnapshotListener { snapshot, error ->

            scheduleList.clear()

            if( error != null )
                return@addSnapshotListener

            if( snapshot != null ) {

                for( document in snapshot ) {
                    val category         = document.getString(ScheduleConstants.CATEGORY).toString()
                    val startTime        = document.getString(ScheduleConstants.START_TIME).toString()
                    val endTime          = document.getString(ScheduleConstants.END_TIME).toString()
                    val request          = document.getString(ScheduleConstants.REQUEST).toString()
                    val managerUid       = document.getString(ScheduleConstants.MANAGER_UID).toString()
                    val managerName      = document.getString(ScheduleConstants.MANAGER_NAME).toString()
                    val registrationTime = document.getString(ScheduleConstants.REGISTRATION_TIME).toString()

                    scheduleList.add(UserScheduleDTO(
                                                    uid,
                                                    category,
                                                    startTime,
                                                    endTime,
                                                    request,
                                                    managerUid,
                                                    managerName,
                                                    registrationTime
                    ))

                }
                // list clear 후 새로 고침을 해준다.
                notifyDataSetChanged()

            } else println("data null")
        }
}

 

 

(참고)

1. Firebase RealtimeDatabase

 

https://gift123.tistory.com/19

 

안드로이드 개발(2) -파베 RealtimeDatabase 사용 팁

안녕하세요 Loner입니다. 다른 블로그보면 Toy 프로젝트 하나 만들어서 코드를 멋지게 예시를 드는데,, 평소에 할일이 많아서 Toy 프로젝트 만들기가 버겁네요.. (아니면 내가 불성실한거거나..) 그

gift123.tistory.com

https://firebase.google.com/docs/database/android/read-and-write?hl=ko 

 

Android에서 데이터 읽기 및 쓰기  |  Firebase 실시간 데이터베이스

Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기 이 페이지는 Cloud Translation API를 통해 번역되었습니

firebase.google.com

 

 

2. Firebase Firestore

 

https://firebase.google.com/docs/firestore/query-data/get-data?hl=ko 

 

Cloud Firestore로 데이터 가져오기  |  Firebase

Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기 이 페이지는 Cloud Translation API를 통해 번역되었습니

firebase.google.com

https://firebase.google.com/docs/firestore/query-data/listen

 

Cloud Firestore로 실시간 업데이트 받기  |  Firebase

Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기 이 페이지는 Cloud Translation API를 통해 번역되었습니

firebase.google.com

 

 

728x90