[Android, Kotlin] Firebase DB에서의 각 Listener별 차이점 (Value, Single, Child)
Android

[Android, Kotlin] Firebase DB에서의 각 Listener별 차이점 (Value, Single, Child)

Firebase Realtime DB를 사용 할 때,

리스너를 등록하여 DB 내 값이 변경 될 때마다 해당 변경 사항을 동기화시켜 리사이클러뷰 등의 리스트를 업데이트 할 일이 잦다.

 

이 때 등록 할 수 있는 리스너는 3가지 종류가 있다.

1. ValueEventListener

2. SingleValueEventListener (DatabaseReference.addListenerForSingleValueEvent(ValueEventListener) 형태로)

3. ChildEventListener

 

리스너를 사용 중 각 리스너 별 동작에 따른 차이점과 사용 형태가 궁금해져 직접 3가지 형태의 리스너를 달고

데이터가 추가 되었을 때의 결과를 확인해보았다.

 

먼저, 초기에 구성되어 있는 기본 DB 상태이다.

"Users" path 내에 4개의 child가 존재하고 있는 상태이다.

해당 DB 상태에서 아래와 같이 3가지 형태의 리스너를 달고 앱을 실행해보았다. (필요한 코드만 삽입)

 

//DatabaseReference
private val db: DatabaseReference by lazy {
    Firebase.database.reference
}

// ValueEventListener
private val valueEventListener = object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            for (data in snapshot.children) {              
                Log.e("Listeners", "ValueEventListener-onDataChange : ${data.value}", )
            }           
        }
        override fun onCancelled(error: DatabaseError) {}
}

// ChildEventListener
private val childEventListener = object : ChildEventListener {
        override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
            Log.e("Listeners", "ChildEventListener-onChildAdded : ${snapshot.value}", )
        }

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

        override fun onChildRemoved(snapshot: DataSnapshot) {}

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

        override fun onCancelled(error: DatabaseError) {}
}

// SingleEventListener
private val singleEventListener = object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            for (data in snapshot.children) {
                Log.e("Listeners", "SingleEventListener-onDataChange : ${data.value}", )
            }
        }

        override fun onCancelled(error: DatabaseError) {}

}

....

override fun onResume() {
        super.onResume()
        // ValueEventListener 설정
        db.child("Users").addValueEventListener(valueEventListener)
        // SingleEventListener 설정
        db.child("Users").addListenerForSingleValueEvent(singleEventListener)
        // ChildEventListener 설정
        db.child("Users").addChildEventListener(childEventListener)
}

 

초기 앱 실행 시 리스너에서 받아오는 결과는 다음과 같다.

 

 

ValueEventListener, SingleEventListener, ChildEventListener 모두 초기 앱 실행 시에는 child를 모두 받아온다.

 

 

이제, 다음과 같이 Users DB에 새로운 child를 하나 추가시켰을 때 리스너 로그를 보도록 한다.

차이점은 해당 부분에서 발생한다.

DB에 새로운 child 추가

 

 

SingleEventListener의 경우는 앱 초기 실행에 한 번 호출되고, 그 후에는 삭제되어 동작하지 않았다.

ValueEventListener의 경우는 추가된 child를 포함하여 모든 child를 모두 읽어온다.

ChildEventListener의 경우는 추가된 child만을 읽어온다.

 

 

해당 결과를 통해, 각 리스너의 적절한 사용은 다음과 같다.

 

SingleEventListener - 초기 1회에만 데이터를 받아오며, 이후 데이터의 변경 없이 UI를 초기화 하는 상황에서 사용

ValueEventListener - path 내의 데이터의 변경에 대해 path 내의 모든 데이터를 받아와야 하는 상황에서 사용

ChildEventListener - path 내의 데이터의 변경에 대해 변경된 데이터만을 받아와야 하는 상황에서 사용

 

 

 

 

참고 : https://stack07142.tistory.com/282

 

Firebase Database 데이터 읽기, 3가지 방법

Firebase Database 데이터 읽기, 3가지 방법 Firebase Database에서 데이터를 읽는 방법으로는 아래와 같이 3가지가 있습니다. 1. addValueEventListener() 메소드를 이용하여 DatabaseReference에 ValueEvent..

stack07142.tistory.com