파이어 베이스를 사용해보는 것이 이번이 두 번째인데
너무나도 바보 같은 짓으로 삽질을 무진장 해버려서 기록을 남기려고 한다.
그리고 저 처럼 혼자 인터넷으로 공부해서 옆에서 올바른 방법을 지적해 줄 사람이 없는 분들을 위해 남깁니다.
1. 첫번째 삽질
private fun importKeywords(){
FirebaseDatabase.getInstance().reference
.child("keywords")
.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
// 파이어베이스에서 데이터를 읽어옴
num = (대충 값을 가져오는 코드)
}
})
// 읽어온 데이터를 리턴함
return num
}
내가 처음에 의도하고자 했던 것은
내가 데이터베이스에서 값을 읽고 싶을 때 importKeywords 메서드를 호출하고
num에다가 값을 저장한 다음 return 해주는 것이었다.
근데 내 예상과는 다르게 자꾸 반환 값이 null로 뜨는 문제가 생겼다.
그래서 여기 뜯어보고 저기 뜯어보고 별짓을 다 해보다가
"아! 파이어 베이스에서 데이터를 읽어오는 시간이 느려서 기다리다가 지쳐서 먼저 return 했구나!"라고 생각했다.
데이터를 불러오는 것은 비동기식으로 작동하기 때문에 반환 값은 항상 null이 된다.
아래 링크는 나처럼 삽질한 외국인들이 질문한 게시물이다.
2. 두 번째 삽질
private fun importKeywords(){
FirebaseDatabase.getInstance().reference
.child("keywords")
.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
(값을 가져오는 코드)
(값을 변화시키는 코드)
}
})
}
리턴된 값으로 하고 싶었던 작업이 값을 변화시켜서 다시 업로드하는 것이었다.
예를 들면, '1'이라는 값을 읽어와서 '+1'을 하고 다시 데이터베이스에 저장하고 싶었다.
값을 리턴하는 게 안되니까 이렇게 onDataChange 안에 연달아서 코드를 작성했다.
결과는?
난 더하기 1만 하고 싶었는데 숫자가 미친 듯이 올라갔다. 무한루프에 빠져버린 것이다.
3. 해결 방법
그 이후로 이것저것 시도해보다가 나의 무지함을 깨달았다.
나는 여태까지 "addValueEventListener = 데이터베이스에서 값을 불러올 때 쓰는 거"라고 생각했다는 것이다.
정확히 말하자면, 값의 변화가 있으면 알려주는 리스너이다.
버튼 눌림을 감지하는 setOnClickListener도 한 번 등록해 놓으면 이벤트가 발생할 때 알려주는 것처럼
addValueEventListener도 한 번 등록해 놓으면 이벤트(데이터의 변화)가 발생할 때 알려주는 것이다.
데이터가 필요할 때마다 부르는 메서드 같은 놈이 아니라는 것이다.
두 번째 삽질 때 무한루프에 빠졌던 이유가
값을 변화시키니까 -> 리스너가 onDataChange를 호출하고 -> 또 값을 변화시키고 -> 리스너가 on DataChange를 호출하고 -> ... 반복된 것이다.
class MainActivity : AppCompatActivity() {
(전역변수)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
FirebaseDatabase.getInstance().reference
.child("keywords")
.addValueEventListener(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {
}
override fun onDataChange(p0: DataSnapshot) {
(값을 가져와서 전역변수에 저장)
}
})
}
}
결국엔 그냥 위 코드처럼 딱 한 번만 리스너를 등록하면
실시간으로 데이터베이스의 값 변화를 감지해서
만약 변화가 있다면 onDataChange를 그때그때 호출해 줄 것이기 때문에
전역 변수에 저장된 값도 그때그때 바뀐다는 것이다.
세상에 이걸 몰라서 하루 종일 고생한 거 생각하면 어이가 없다.
대체 난 이걸 왜 생각 못했지?...
혹시 나처럼 바보 같은 생각을 하지 않았는데도
진짜 파이어 베이스의 딜레이 (대기 시간) 때문에 문제가 생기는 부분이 있다면
1. 콜백 함수
2. EventBus
이렇게 해결한 분들이 있다고 하니 참고하면 좋을 것 같다.
'앱 제작 > 키워드 알림 앱' 카테고리의 다른 글
[코틀린] infinite/endless scroll(무한 스크롤)과 recyclerView (14) | 2021.01.08 |
---|---|
[파이썬] FCM을 통해 앱으로 푸시알림 보내기 (22) | 2021.01.04 |
subscribeToTopic 한글을 주제로 구독하기 :: 푸시알림 구독 서비스 구현 (12) | 2021.01.02 |
[Kotlin] FCM 푸시 알림 구현하기 (15) | 2020.12.31 |
키워드 알림 앱 만들기 :: 구상하기 (0) | 2020.12.30 |
댓글