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를 하나 추가시켰을 때 리스너 로그를 보도록 한다.
차이점은 해당 부분에서 발생한다.
SingleEventListener의 경우는 앱 초기 실행에 한 번 호출되고, 그 후에는 삭제되어 동작하지 않았다.
ValueEventListener의 경우는 추가된 child를 포함하여 모든 child를 모두 읽어온다.
ChildEventListener의 경우는 추가된 child만을 읽어온다.
해당 결과를 통해, 각 리스너의 적절한 사용은 다음과 같다.
SingleEventListener - 초기 1회에만 데이터를 받아오며, 이후 데이터의 변경 없이 UI를 초기화 하는 상황에서 사용
ValueEventListener - path 내의 데이터의 변경에 대해 path 내의 모든 데이터를 받아와야 하는 상황에서 사용
ChildEventListener - path 내의 데이터의 변경에 대해 변경된 데이터만을 받아와야 하는 상황에서 사용
참고 : https://stack07142.tistory.com/282