본문 바로가기

안드로이드 Android

안드로이드 개발 (3) FireBase 게시판 댓글

Loner 입니다. 주말이 가까워지면 항상 사이드 협업 프로젝트를 진행합니다.

평일은 메인 외주프로젝트를 진행하고 있습니다. 

 

마음 같아서는 메인 프로젝트 관련해 포스팅을 하고 싶지만,

가능하면 사이드 협업 위주로 포스팅을 진행하는 중입니다.

(내 성격상 좋아하는걸 말하다 보면 비밀로 해야할 정보를 말하는 실수 할까봐 아예 입을 닫아버립니다.)

 

사이드 협업을 3개 진행중인데 

한개는 서버담당자가 따로 존재하고,

나머지 두개는 사이드 협업을 안드 개발자 멤버들이 모여서 파이어베이스로 퉁치게 됬습니다.

(안드로이드 개발자끼리 협업 하면 좋은점은 서로 코드를 보며 배워갑니다. 단점은 서버가 그립다.)

 

스케줄 상 금요일 저녁 마다 사이드 프로젝트 2개의 작업을 추가로 진행합니다.

오늘은 작업했던 작업은 아래와 같습니다.

댓글 만들기 :RealTimeDataBase

첫번째 작업부터 정리하도록 하겠습니다.

언어:Java

FireBase RealTimeDataBase 이용한 게시판 댓글 작업입니다.

이미 이슈를 해결한 이미지..

이슈 => 댓글이 2배로 복사 되는 문제가 있었습니다.

알고보니 Db구조와 비동기 처리하면서 생긴 문제 였습니다.

이 글을 보시는 분에게 상세히 설명드리기 힘듬으로 해결한 후의 상황으로 댓글 만드는 법을 남겨두겠습니다.

 

기본적으로 댓글을 달려면 게시물이 있어야합니다.

보통은 ListView나 RecyclerView로 리스트형식으로 만든 뒤

아이템을 클릭하면 클릭한 id 정보가 자세한 화면으로 넘어가게끔 설정합니다.

        Adapter.setOnItemClick((board, users) -> {
            Intent intent = new Intent(getContext(), DetailActivity.class);
            intent.putExtra(SELECT_Idx, tempboard.getId());
            startActivity(intent);
        });

 

상세 화면에서 이전 화면에서 받아온 id를 기준으로 파이어베이스 조회를 해서 게시물 db를 가져옵니다.

(혹시 캐싱 처리 효과를 비슷하게 넣고 싶은 사람은 id가 아니라 해당 아이템의 db를 넘겨서 ui를 꾸며 준뒤 

파이어베이스에서 db의 id를 참조해서 실시간 데이터를 받아오면 캐시 효과를 비슷하게 느낄 수 있음)

 

이제 게시물 상세화면에서 승부를 봐야합니다. 

게시물의 주 구조는 보통 아래와 같이 구성이 됩니다.

1) 게시물을 작성한 유저 정보 

2) 게시글 내용 및 시간

3) 좋아요 기능

4) 댓글 기능 

5) 사진 첨부 

위의 구성들로 되어있기 때문에 주로 아래와 같이 db를 짜주면 좋습니다.

public class TempBoard implements Serializable {

    private String id; // 게시물 + 랜덤 99999 그외 시간 기준 방법 등등..
    private String writeId ;    //글 작성자 (유저데이터 테이블 = User.usersName)
    private String contentTitle;        //글 제목
    private String text;      //글 내용
    private String createAt;  //글 작성,수정 시간
    private ArrayList<String> likeList;            //좋아요 수
    private ArrayList<String> imgList;    // 이미지 url 링크들
.. 아래는 게타 세타

}

(실제 사이드 프로젝트에서 쓰는 db를 공개 할 수 없으니 임의로 만들었습니다.)

위 db를 살펴봐서 해법들은 아래와 같습니다. 

 

1. 게시물을 작성한 유저 정보

-> writeId 기준으로 파이어베이스에서 유저데이터를 가져와서 ui에 뿌립니다. 

 

2. 게시글 내용 및 시간

-> contentTitle 과 createAt 를 사용해서 내용 및 시간을 표시합니다.

 

3. 좋아요 기능

-> 서버가 있다면 join해서 받으면 되지만, 파베 같은 경우 noSql방식이라 join이 안되기 때문에 좋아요 누를시 사용자의 likeList에 userId를 차곡차곡 담아버립니다.

likeList안에 좋아요를 누른 userId가 있다면 좋아요 취소 하기 / 없다면 좋아요 추가 하기

 

4. 댓글 기능 

-> 위 db에서는 할일이 없다. 아래 내용에서 이어서 설명하겠습니다.

 

5. 사진 첨부 

-> imgList 에서 이미지를 뿌려줍니다. 안드로이드의 경우 Glide를 사용하는 것이 대표적입니다. 파이어베이스 서버를 이용할시 파이어베이스 스토리지를 이용해줍시다. 

(파이어베이스 스토리지 단점은 구글 드라이브를 사용하기 때문에 uri 불러오기가 느리다. 가능하면 서버 저장소를 하나 두는게 좋다. )

 

그러면 게시판 자체는 끝납니다. 이 얼마나 쉬운가... 문제는 댓글입니다.

 

댓글 데이타를 위와 같은 방식으로 만듭니다. 

그럼 댓글을 보겠습니다. 댓글은 크게 3개의 경우로 나뉩니다.

1) 게시물에 달린 댓글 

2) 댓글의 답글 

3) 댓글의 답글의 답글 

 

UI는 FireBase에서 지원해주는 RecyclerView 및 관련 게시물 만드는 라이브러리를 사용하는 방법이 있고 

기본적으로 RecyclerView 만들고 아이템마다 RecyclerView를 하나 더 만드는 방법이 있습니다.

그외에도 리니어 레이아웃을 사용하는 방법등등 다양하지만 

저는 RecyclerView를 만들고 아이템 마다 RecylcerView를 하나 더 사용하는 중첩 리싸이클러뷰를 사용하는 방법을 

택했습니다. 

 

 

게시물 자체에 사용할 댓글을 표시할 리싸이클러뷰 하나를 만들고

댓글의 답글들을 표시할 리싸이클러뷰를 준비합니다. 

우선 어댑터를 두개를 만듭니다.

하나는 게시물의 일반 댓글용

다른 하나는 게시물의 댓글의 댓글용

 

첫번째 어댑터 item layout에 recyclerView를 만듭시다.

RecyclerView에 사용할 Adapter를 만드는데 onBindViewHolder에

위 itemLayout에 만든 RecyclerView에 .setAdapter()를 해줍시다. 

 

위와 같이 그릴 item layout도 만들면 됩니다.

그래서 결론적으로

Adpater 두개와

item layout 두개가 필요합니다. 

 

댓글의 댓글에서 첫번째 화살표 표시는 onBindVIewHolder에서 

position이 0일때만 화살표 ui를 visible 해주면 됩니다. 

 

*댓글의 댓글 리사이클러뷰에서 댓글의 댓글의 댓글은 일렬로 아이템이 생성 표시 되도록 할겁니다. 

 

댓글의 db는 아래와 같이 만듭니다. 

public class TempReply implements Serializable {
    private String id; // 비밀 방법은 id 만드는 방법은 많다.
    private String board; // 댓글이 속한 게시물
    private String describe;// 댓글내용
    private String WriteId;// 댓글 작성자
    private String time;// 댓글 작성 및 수정 일시
    private String parent; //댓글의 답글 일시 댓글 달 해당 db id 
    
    // 댓글의 답글의 답글..답글.. 댓글속의 댓글 일때 맨 꼭대기 댓글을 적음 depth가 1이면 parent와 같음 
    private String root; 
    
    private boolean mode; // 댓글의 답글 달은 댓글인지 체크 //true댓글 안의 댓글 //false 일반 게시물 댓글
    private ArrayList<String> likeList;// 댓글 좋아요수
    private ArrayList<String> ToReplys;// 댓글의 답글 리스트 //답글갯수로도 작용할것
    
    //아래는 getta setta 
    }

1) 게시물에 달린 댓글 

-> board를 참고해서 해당 게시판 id를 가진 댓글 db들을 파이어베이스에서 다 가져옵니다. 

wirteId를 참고해서 userData를 가져오고 describe와 time을 참고해서 댓글의 내용과 시간을 표시해줍니다. 

likeList와 ToReplys로 좋아요 갯수, 답글의 갯수를 표시해줍니다.

 

2) 댓글의 답글 

-> 1)에서 가져온 댓글리스트를 mode를 참고해서 true 인것만 필터링해서 리스트를 다시 만들어서 

중첩된 RecyclerView에 넘겨줍니다.

root(최상위 댓글의 id) 와 parent (상위 댓글의 id)를 확인해서 해당 댓글이 어느 댓글로 부터 달린건지 확인해서 

조건에 맞다면 아이템으로 추가해줍니다.

댓글의 댓글이 1개 뿐이라면 root와 parent의 id는 같습니다.

상위 ReclycerView의 댓글 db를 받은 다음 리스트를 반복문으로 돌려서 parent와 root가 동시에 맞는지 비교해서 찾으면 됩니다.

 

3) 댓글의 답글의 답글 

-> 2)와 같은 방법으로 하면 댓글의 답글의 답글....답글.. 이런 댓글들이 아래로 쭉 만들어집니다.

 

위와 같은 방식으로 댓글을 만들 수 있습니다. 

 

그외에 db의 필드 값들은 해당 db를 insert할 때 상황에 맞게 고려해서 값을 업데이트 해주면 됩니다. 

코드까지 응용한 자세한 설명들은 하지 않았습니다.

하지만 충분히 자료들은 많으니 부족한 부분들은 따로 참고하신다면 금방 만들 수 있습니다.