안녕하세요 선생님, 우선 강의 내용과 직접적으로 관련된 질문이 아니라 죄송합니다. 댓글 관련 오류가 몇 가지 발생해 여쭤봅니다.
BoardReadActivity.kt
생략
// 댓글 목록 정보 가져옴
fun getCommentListData(key: String) {
생략
// 댓글 헤더에 댓글 개수 출력
binding.commentCountText.text = commentKeyList.count().toString()
생략
}
기존 댓글 2개가 있는 상황에서 새 댓글을 1개 입력하면 댓글 개수가 3이 되어야 하는데요,
2(기존) + 3(기존2업뎃1) = 5(누적)로 출력이 됩니다.
또한 방금 막 작성한 댓글 a의 수정 페이지로 넘어가면
추가된 댓글이 즉시 반영되지 않아 맨 위 댓글인 user1이 불러와지며
댓글 a가 아닌 맨 위 댓글이 수정됩니다.
마찬가지로 a를 삭제하려해도 user-1이 불러와지며
삭제되는 댓글도 a가 아닌 user-1입니다.
수정과 삭제를 반복하면 댓글 카운트는 계속 늘어나고, 이 과정에서 앱이 죽기도 합니다.
게시글을 한 번 나갔다 들어와야 댓글 수가 제대로 카운트 돼서 어떻게 해야 할지 도움 요청드립니다. 코드 전체는 깃허브에 업로드 해 놓았습니다. https://github.com/shinyelee/my-solo-life
Activity 라이프 사이클에 변화가 있을 때마다
저 댓글 수를 불러오는 것으로 코드가 되어 있다면
라이프사이클이 변경될 떄 값을 초기화해주시면 됩니다.
자바로 되어있긴 하지만, 한번 라이프사이클에 대해서 공부해보시겠어요?
https://www.youtube.com/watch?v=gYacRFMEPjk
답글
신예리
2022.09.05 오전 12:55네, 유튜브 다 봤고 안드로이드 공식 문서도 읽어봤습니다.
이제 댓글을 등록할 때는 댓글 개수가 제대로 카운트 되고
현재 문제점들을 요약하자면 아래와 같은데 어떻게 해결해야 할 지 방향을 잡아주실 수 있으실까요? 전체 코드는 깃허브에 올려 놓았습니다. https://github.com/shinyelee/my-solo-life
댓글 작성 후 글읽기 액티비티가 재시작할 때 페이지가 로딩되는 동안 블랙 스크린이 뜨는 현상
댓글 등록/수정/삭제시 간헐적으로 튕기는 현상
댓글 수정/삭제 후 댓글 개수가 제대로 반영되지 않는 현상(누적으로 업데이트됨)
안녕하세요.
1/2 번 문제같은 경우에는 로그를 보면 알 것 같습니다.
저 앱이 죽는 순간에 logcat에 찍히는 정보를 공유해주시겠어요?
3번 문제의 경우, Firebase에서 받아온 댓글을 읽어와서 보여주는 것이 맞으실까요?
그렇다면 읽어오는 부분에 로그를 찍어서 저 부분이 어떻게 실행되는지 알려주시겠어요?
답글
신예리
2022.09.16 오후 6:57https://github.com/shinyelee/my-solo-life
댓글 연달아 등록시 logcat입니다.
2022-09-16 18:25:04.725 4916-5233/com.shinyelee.my_solo_life E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
2022-09-16 18:25:04.726 4916-5233/com.shinyelee.my_solo_life E/StorageException: { "error": { "code": 404, "message": "Not Found." }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:289)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:76)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:68)
at com.google.firebase.storage.GetDownloadUrlTask.run(GetDownloadUrlTask.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
2022-09-16 18:25:10.409 4916-5244/com.shinyelee.my_solo_life E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
2022-09-16 18:25:10.410 4916-5244/com.shinyelee.my_solo_life E/StorageException: { "error": { "code": 404, "message": "Not Found." }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:289)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:76)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:68)
at com.google.firebase.storage.GetDownloadUrlTask.run(GetDownloadUrlTask.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
2022-09-16 18:25:12.772 4916-4916/com.shinyelee.my_solo_life E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.shinyelee.my_solo_life, PID: 4916
java.lang.NullPointerException
at com.shinyelee.my_solo_life.board.BoardReadActivity.getBinding(BoardReadActivity.kt:33)
at com.shinyelee.my_solo_life.board.BoardReadActivity.access$getBinding(BoardReadActivity.kt:27)
at com.shinyelee.my_solo_life.board.BoardReadActivity$getCommentListData$postListener$1.onDataChange(BoardReadActivity.kt:177)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2022-09-16 18:25:13.952 5261-5291/com.shinyelee.my_solo_life E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
2022-09-16 18:25:13.953 5261-5291/com.shinyelee.my_solo_life E/StorageException: { "error": { "code": 404, "message": "Not Found." }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:289)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:76)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:68)
at com.google.firebase.storage.GetDownloadUrlTask.run(GetDownloadUrlTask.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
2022-09-16 18:25:20.656 5261-5307/com.shinyelee.my_solo_life E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
2022-09-16 18:25:20.657 5261-5307/com.shinyelee.my_solo_life E/StorageException: { "error": { "code": 404, "message": "Not Found." }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:289)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:76)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:68)
at com.google.firebase.storage.GetDownloadUrlTask.run(GetDownloadUrlTask.java:77)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
2022-09-16 18:25:22.551 5261-5261/com.shinyelee.my_solo_life E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.shinyelee.my_solo_life, PID: 5261
java.lang.NullPointerException
at com.shinyelee.my_solo_life.board.BoardReadActivity.getBinding(BoardReadActivity.kt:33)
at com.shinyelee.my_solo_life.board.BoardReadActivity.access$getBinding(BoardReadActivity.kt:27)
at com.shinyelee.my_solo_life.board.BoardReadActivity$getCommentListData$postListener$1.onDataChange(BoardReadActivity.kt:177)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2022-09-16 18:27:33.572 1957-5380/com.google.android.gms E/ciiw: ~~*~ Channel {0} was not shutdown properly!!! ~*~*~*
Make sure to call shutdown()/shutdownNow() and wait until awaitTermination() returns true.
java.lang.RuntimeException: ManagedChannel allocation site
at ciiv.<init>(:com.google.android.gms@201817022@20.18.17 (040700-311416286):3)
at ciiw.<init>(:com.google.android.gms@201817022@20.18.17 (040700-311416286):2)
at cicn.b(:com.google.android.gms@201817022@20.18.17 (040700-311416286):21)
at sdn.a(:com.google.android.gms@201817022@20.18.17 (040700-311416286):24)
at sdn.a(:com.google.android.gms@201817022@20.18.17 (040700-311416286):31)
at afgm.a(:com.google.android.gms@201817022@20.18.17 (040700-311416286):12)
at com.google.android.libraries.matchstick.net.SilentRegisterIntentOperation.a(:com.google.android.gms@201817022@20.18.17 (040700-311416286):179)
at com.google.android.libraries.matchstick.net.SilentRegisterIntentOperation.f(:com.google.android.gms@201817022@20.18.17 (040700-311416286):38)
at com.google.android.libraries.matchstick.net.SilentRegisterIntentOperation.onHandleIntent(:com.google.android.gms@201817022@20.18.17 (040700-311416286):164)
at com.google.android.chimera.IntentOperation.onHandleIntent(:com.google.android.gms@201817022@20.18.17 (040700-311416286):2)
at qgf.onHandleIntent(:com.google.android.gms@201817022@20.18.17 (040700-311416286):4)
at cui.run(:com.google.android.gms@201817022@20.18.17 (040700-311416286):5)
at cuh.run(:com.google.android.gms@201817022@20.18.17 (040700-311416286):9)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
2022-09-16 18:27:34.298 1957-5380/com.google.android.gms E/MS_RegisterService: Exception during register request.
ciau: UNAUTHENTICATED: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
at ciat.c(:com.google.android.gms@201817022@20.18.17 (040700-311416286):3)
at sdn.a(:com.google.android.gms@201817022@20.18.17 (040700-311416286):48)
at afgm.b(:com.google.android.gms@201817022@20.18.17 (040700-311416286):6)
at com.google.android.libraries.matchstick.net.SilentRegisterIntentOperation.a(:com.google.android.gms@201817022@20.18.17 (040700-311416286):178)
at com.google.android.libraries.matchstick.net.SilentRegisterIntentOperation.f(:com.google.android.gms@201817022@20.18.17 (040700-311416286):38)
at com.google.android.libraries.matchstick.net.SilentRegisterIntentOperation.onHandleIntent(:com.google.android.gms@201817022@20.18.17 (040700-311416286):164)
at com.google.android.chimera.IntentOperation.onHandleIntent(:com.google.android.gms@201817022@20.18.17 (040700-311416286):2)
at qgf.onHandleIntent(:com.google.android.gms@201817022@20.18.17 (040700-311416286):4)
at cui.run(:com.google.android.gms@201817022@20.18.17 (040700-311416286):5)
at cuh.run(:com.google.android.gms@201817022@20.18.17 (040700-311416286):9)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
신예리
2022.09.16 오후 7:01https://github.com/shinyelee/my-solo-life
댓글 연달아 삭제시 debug입니다.
--------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.shinyelee.my_solo_life, PID: 6205
java.lang.NullPointerException
at com.shinyelee.my_solo_life.board.BoardReadActivity.getBinding(BoardReadActivity.kt:33)
at com.shinyelee.my_solo_life.board.BoardReadActivity.access$getBinding(BoardReadActivity.kt:27)
at com.shinyelee.my_solo_life.board.BoardReadActivity$getCommentListData$postListener$1.onDataChange(BoardReadActivity.kt:177)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
개복치개발자
2022.09.19 오전 1:18안녕하세요.
뭔가 길어지니깐 저도 헷갈리기 시작하네요
오류 메세지를 보니깐 404 not found / null point exception 입니다.
잘못된 정보를 받아와서 보여주는 것 같은데
로직을 생각해보자면
댓글을 받아와서
뭔가 수정 및 삭제를 해주고 있는데
삭제 및 수정을 하고나서 변경된 데이터가 앱에 저장된 것과 firebase에 다른 상태로 보입니다.
이럴 때 가장 간단한 해결방법은 저 수정 삭제를 누르고 난 이후에, 이전에 firebase에서 받아온 정보를 저장하는 변수의 값을 초기화 시켜주는 방법이 있습니다.
저기 에러가 발생하는 라인이 몇번쨰인지를 보시고, 어떤 변수에서 문제가 발생하는지 살펴보시고 어려우시면 스크린샷도 함께 공유해주시겠어요?
신예리
2022.09.21 오전 4:06StorageException과 NullPointerException이 뜨는 원인을 찾은 것 같습니다. 현재 댓글 수정/삭제 로직은 아래와 같은데요.
1) BoardReadActivity(게시글 하나 보는 페이지)에서 수정/삭제하고자 하는 댓글 클릭
2) CommentEditActivity(댓글 수정/삭제 페이지) 시작
3) 댓글 삭제 버튼을 누르면 댓글이 수정/삭제됨과 동시에 BoardEditActivity가 종료됨
4) BoardReadActivity로 돌아감(실제로는 CommentEditActivity에 가려져있던 액티비티가 드러난 것)
이 때 4번의 BoardActivity를 새로고침해 댓글 수정/삭제 내역을 반영해야 하는데 실제로는 2번의 (댓글 수정/삭제 전인) 화면을 그대로 띄워줘 문제가 발생하는 것으로 보입니다.
1) BoardReadActivity에서 NullPointerException이 뜰 때 댓글 개수를 다시 받아오거나
2) BoardEditActivity가 종료될 때 BoardReadActivity가 댓글 개수를 다시 받아오게 만들고자 하는데
http://daplus.net/android-android%EC%97%90%EC%84%9C-%ED%99%9C%EB%8F%99-%EC%9E%AC%EB%A1%9C%EB%93%9C/
https://www.masterqna.com/android/97604/%EC%95%A1%ED%8B%B0%EB%B9%84%ED%8B%B0-%EC%A2%85%EB%A3%8C-%ED%9B%84-%EC%9D%B4%EC%A0%84-%ED%94%84%EB%9E%98%EA%B7%B8%EB%A8%BC%ED%8A%B8%EB%A1%9C-%EC%9D%B4%EB%8F%99-%EC%8B%9C-%EA%B0%B1%EC%8B%A0-%EB%B0%A9%EB%B2%95
위 글들을 참고해봐도 해당 기능이 잘 구현되지 않아 재질문드립니다.
신예리
2022.09.21 오전 4:18에러가 발생하는 코드는 주석으로 표시했습니다.
또한 Firebase Realtime database의 경우 데이터 변경이 일어날 경우, 새롭게 데이터를 받아오는 것이 자동으로 실행되니 이 부분 고려하셔서 로그를 찍어보시면 좋을 것 같습니다.
답글
신예리
2022.09.17 오전 12:01https://github.com/shinyelee/my-solo-life
3번 문제 관련해 BoardReadActivity.kt 코드입니다.
신예리
2022.09.17 오전 12:03https://github.com/shinyelee/my-solo-life
로그를 확인해보니 댓글 데이터 자체는 제대로 받아오고 있습니다.
2022-09-17 00:01:38.535 534-896/system_process I/ActivityTaskManager: START u0 {cmp=com.shinyelee.my_solo_life/.board.BoardReadActivity (has extras)} from uid 10122
2022-09-17 00:01:38.627 6349-6349/com.shinyelee.my_solo_life D/BoardReadActivity: DataSnapshot { key = -NBR-KRzCh8X18kzS04y, value = {uid=qwgynbq1wsWwVlxdrieokzQRXpd2, main=1212222, time=22-09-08 16:30} }
2022-09-17 00:01:38.627 6349-6349/com.shinyelee.my_solo_life D/BoardReadActivity: DataSnapshot { key = -NBR-NYf7D93gn1mACPo, value = {uid=qwgynbq1wsWwVlxdrieokzQRXpd2, main=313333, time=22-09-08 16:30} }
2022-09-17 00:01:38.627 6349-6349/com.shinyelee.my_solo_life D/BoardReadActivity: DataSnapshot { key = -NC4bUFJ0_6BeJ43hmm6, value = {uid=pJYqGCYe5JcGI5Qrfc5w6F8kJ633, main=1111, time=22-09-16 09:25} }
2022-09-17 00:01:38.630 534-580/system_process I/ActivityTaskManager: Displayed com.shinyelee.my_solo_life/.board.BoardReadActivity: +94ms
개복치개발자
2022.09.19 오전 1:19넵
이 부분의
onchange 부분에서 댓글 부분을 onchange부분에 받아온 댓글의 댓수로 변경해주는 코드를 추가해보시겠어요?
신예리
2022.09.21 오전 4:12위 코드에서
를
로 바꿔주니 댓글 개수가 제대로 출력됩니다!
신예리
2022.09.21 오전 4:21댓글 카운팅은 고쳤는데, 댓글이 매칭되지 않는 문제가 재발했습니다.
댓글을 3개 등록해 111 -> 11 -> 1 순으로 삭제 시도했는데
개복치개발자
2022.09.23 오후 11:43실제로 저 삭제 버튼을 눌렀을 때 원하는 게시글이 클릭되고 있는게 맞나요?
Adapter부분에서 onclick을 했을 때, 어떤 게시글이 가고 있는지 로그를 찍어봐야 할 것 같습니다.
그리고, 앱이 죽는 부분은 죽는 순간의 로그를 한번 확인해보시겠어요?
개복치개발자
2022.09.23 오후 11:44질문이 어려가지로 헷갈려서 구분이 조금 어렵네요.
새롭게 정리해서 별도의 질문으로 올려주시겠어요?