[Firebase] 실시간 채팅방 만들기 - Realtime Database - 4 (채팅방 마지막 메시지)

원준·2023년 10월 12일

Firebase

목록 보기
8/11

레이아웃 코드는 제외한다.

우선 채팅방 리스트를 만들어 볼까?

1. 선언 및 초기화

  • 인증과 경로 설정, 채팅 id가 필수로 들어가야한다!
    • RecyclerView는 당연히 필수고~
private FirebaseAuth mAuth;
DatabaseReference myRef;
  • 초기화를 해볼까?
@Override
protected void onCreate(Bundle savedInstanceState) {
	//....
    mAuth = FirebaseAuth.getInstance();
    // 인증된 사용자가 존재하지 않으면, 로그인 화면으로 돌아간다.
    if(mAuth.getCurrentUser() == null){
      Intent intent = new Intent(ChatActivity.this, LoginActivity.class);
      startActivity(intent);

      finish();
      return;
    }
    
    // 채팅방 경로 설정
    FirebaseDatabase database = FirebaseDatabase.getInstance();
    myRef = database.getReference("ChatRoom").child("chatRooms");
}

2. 채팅방 찾기

  • 인증된 사용자가 포함된 채팅방을 찾아서 값을 넘기자!!
    • onResume() 메서드에 넣기위해 함수로 만들자!!
protected void chatRoomAdd(){
    chatRoomArrayList.clear();

    // ChatRoom/chatRooms의 경로안에 users의 경로중 접속한 자신의 uid와 일치하는 부분을 전부 찾는다. 
    myRef.orderByChild("users/" + mAuth.getCurrentUser().getUid()).equalTo(true)
            .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    for (DataSnapshot data : snapshot.getChildren()){
                        // 찾은 정보들을 전부 ChatRoom 클래스에 담자. 
                        // 찾은 정보들의 키값들이 존재하는데, 고유 키값이니 같이 저장하자. 

                        ChatRoom chatRoom = data.getValue(ChatRoom.class);

                        chatKeyArrayList.add(data.getKey());
                        chatRoomArrayList.add(chatRoom);

                        adapter.notifyDataSetChanged();
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError error) {

                }
            });
}

채팅방의 마지막 메시지를 불러와볼까??

  • Adapter에서 진행하니까 이동하자!!

onBindViewHolder 메서드에서 코드 작성!!

ChatRoom chatRoom = chatRoomArrayList.get(position);

int limit = chatRoom.messages.values().size();// 해당 채팅방의 메시지의 크기가 1이상이면 
if(limit > 0){
    // 메시지의 마지막의 값을 찾습니다. 
    List<Message> messageList = chatRoom.messages.values().stream()
            .sorted(Comparator.comparing(Message::getDate)).skip(limit-1).collect(Collectors.toList());
    Message message = messageList.get(0);

    if(message.getConfirmed()){ // true일 경우 이미지로 출력하기로 하자. 
        holder.imageView.setVisibility(View.VISIBLE);
        FirebaseStorage storage = FirebaseStorage.getInstance();
        StorageReference storageRef = storage.getReference(message.getContent());
        Glide.with(context).load(storageRef).placeholder(R.drawable.baseline_broken_image_24)
                .override(300, 300)
                .diskCacheStrategy(DiskCacheStrategy.DATA)
                .into(holder.imageView);
        holder.txtMessage.setText("");
        
    }else{ // flase일 경우 텍스트로 출력하기로 하자 
        holder.imageView.setVisibility(View.GONE);
        holder.txtMessage.setText(message.getContent());
    }


}else {
    holder.txtMessage.setText("");
}

아니 마지막 메시지 찾는게 뭔데...

  • 솔직히 나도 만들때 엄청나게 힘들게 찾았다.
List<Message> messageList = chatRoom.messages.values().stream()
            .sorted(Comparator.comparing(Message::getDate)).skip(limit-1).collect(Collectors.toList());
  • 이부분인데 내가 생각하는 부분을 작성해보겠다.

chatRoom.messages.values().stream().sorted(Comparator.comparing(Message::getDate))
  • chatRoom 클래스의 hashMap 타입인 messages의 값들을 전부 불러와 stream로 변환하고 내장된 date값을 기준으로 정렬한다.

.skip(limit-1)
  • 상단에 chatRoom의 크기를 구했을텐데, 최대 크기의 -1 만큼 스킵시키면 가장 마지막에 존재하는 값 한개를 제외하고 전부 제외된다.
    • 애초에 정렬에서 오름차순으로 정렬된것임

.collect(Collectors.toList());
  • 그렇게 해서 얻은 값을 list로 변환해서 깨내기 쉽게 해준다!!!

완성된 영상을 보시라!!

profile
공부해보자

0개의 댓글