본문 바로가기
CodeLab/Firebase

Firebase Web 채팅앱 만들기 - Realtime Database를 이용한 채팅기능 구현 - 채팅메세지 전송기능

by 블리드카가 2017. 12. 3.
728x90





이번에는 채팅메세지 전송기능을 구현해보겠습니다. 채팅방화면에서 아래쪽 메세지 입력란에서 입력한 후 엔터키를 누르거나 삼각형 모양의 전송버튼을 누르면 메세지가 전송이 되는 기능을 구현해보겠습니다.




위 코드는 입력란에서 엔터키를 누르거나 전송버튼을 클릭했을 시 saveMessages 메소드가 실행이 되는 코드 입니다.

saveMessages 여러 위치에 저장을 하게 되는데 하나씩 살펴보겠습니다.
var multiUpdates = {};
this.database.ref().update(multiUpdates); // 권한 때문에 먼저 저장해야함

multiUpdates 객체를 선언하고 저장할 위치와 값을 객체에 입력한 뒤 update 메소드로 저장하게됩니다. update 메소드는 이렇게 여러 위치에 한번에 저장할 용도로 사용합니다.

Realtime Database에서 push 메소드는 키값을 자동으로 생성하면서 데이터를 저장하게 됩니다.
하지만 saveMessages 메소드에서는 update메소드를 활용하여 데이터를 저장하므로, 아래의 코드로  키를 생성해서 받을 수 있습니다.
var messageRefKey = this.messageRef.push().key; // 메세지 키값 구하기
saveMessages 메소드는 메세지를 전송할때 3곳에 데이터를 저장하게 됩니다. RoomUsers, UserRooms, Messages 위치 입니다. 

RoomUsers위치에 저장하는 데이터는 채팅방에서 메세지를 처음 보낼 때, 그리고 친구를 채팅방에 초대할 때에만 데이터를 저장하면 됩니다. 채팅방에 메세지가 있는지 체크한 후 저장하는 아래와 같은 코드가 작성되었습니다. 그리고 추후에 적용할 데이터베이스 권한부분 때문에 채팅방을 로드하는 메소드를 다시 한번 실행합니다.

if(this.ulMessageList.getElementsByTagName('li').length === 0){ //메세지 처음 입력 하는 경우
            var roomUserlistLength =this.roomUserlist.length;
            for(var i=0roomUserlistLengthi++){
                multiUpdates['RoomUsers/' +this.roomId+'/' +this.roomUserlist[i]] = true;
            }
            this.database.ref().update(multiUpdates); // 권한 때문에 먼저 저장해야함
            this.loadMessageList(this.roomId); //방에 메세지를 처음 입력하는 경우 권한때문에 다시 메세지를 로드 해주어야함
        }


그 다음 코드는 Messages에 데이터를 저장하기 위해 multiUpdates객체에 저장하는 코드입니다.

var convertMsg FirebaseChat.convertMsg(msg); //메세지  저장
        multiUpdates['Messages/' +this.roomId '/' messageRefKey] = {
            uiduser.uid,
            userNameuser.displayName,
            messageconvertMsg// 태그 입력 방지
            profileImguser.photoURL user.photoURL '',
            timestamp: firebase.database.ServerValue.TIMESTAMP  //서버시간 등록하기
        }

위치는 Messages아래에 방ID 값을 두고 그 아래에 메세지별 key 값을  조합하여 저장할 위치를 구성합니다.
데이터는 메세지 전송자의 uid 값, 메세지 전송자의 이름, 메세지, 프로필이미지, 등록되는 서버 시간 데이터가 저장이 됩니다. 

우선 Message데이터를 한번 convertMsg 메소드를 통해서 메세지에 포함된 태그를 제거하는 코드를 거치게 됩니다. 웹 채팅 특성상 태그의 입력을 막지 않으면 앱자체가 무력화가 될 수 있기 때문입니다.

firebase.database.ServerValue.TIMESTAMP 는 서버시간으로 기록한 시간을 저장할 때 사용합니다. firebase.database.ServerValue.TIMESTAMP 값은 한가지 유의 할점이 있습니다. 데이터를 서버시간으로 저장하고나서, 다시한번 서버와 통신시간을 감안해서 보정된 값을 다시 한번 저장하게됩니다. 데이터의 저장이 두번 일어나게 됩니다.

한번 확인해보겠습니다. loadMessageList 메소드를 아래와 같이 코드를 추가해주세요.




console.log 로 timestamp 값을 받을 것이며, 메세지 수신 이벤트에는 child_added 이벤트에다가 child_changed  이벤트를 추가하였습니다. 메세지를 입력해보시면 메세지는 두개가 입력이 되고 콘솔에 다음과 같이 찍히게됩니다.


timestamp 값을 입력하시는 경우 이 점에 유의하셔야 합니다. 이 부분은 버그가 아니라 의도된 사항이라고 합니다.

채팅창 입력 부분은 완성되었습니다. 하지만 한가지 보완해야할 부분이 있습니다.
메세지를 입력하는 곳의 소스를 살펴보면, input 태그로 되어 있지 않고, div 태그에 contenteditalbe='true' 속성으로 되어 있습니다.




레이아웃 조정을 손쉽게 하기 위해 적용하였습니다만, 한가지 문제가 있습니다. 다른 웹에 있는 내용을 복사해서 붙여넣기를 하면 태그까지 따라오게 됩니다.  


복사 후 붙여넣기 시에 일반 텍스트로 치환하기 위해 아래의 코드를 입력해주세요.





  1. 예제 소개
  2. Firebase 설정하기
  3. Hosting을 활용한 프로젝트 준비 작업
  4. Authentication을 이용한 유저 가입 및 로그인 구현하기
  5. Realtime Database를 이용한 채팅기능 구현 - Reatime Database 특징 및 데이터 구조
  6. Realtime Database를 이용한 채팅기능 구현 - 유저데이터 저장하기
  7. Realtime Database를 이용한 채팅기능 구현 - 유저리스팅 화면
  8. Realtime Database를 이용한 채팅기능 구현 - 채팅화면 및 채팅메세지 리스팅
  9. Realtime Database를 이용한 채팅기능 구현 - 채팅메세지 전송기능
  10. Realtime Database를 이용한 채팅기능 구현 - 채팅방 리스팅화면
  11. Realtime Database를 이용한 채팅기능 구현 - 채팅방 초대 기능
  12. Realtime Database를 이용한 채팅기능 구현 - 접속 중인 유저 표시하기
  13. Storage를 이용한 파일 전송기능
  14. Cloud Messaging과 Functions을 이용한 푸시메세지 기능 - FCM Token 정보 저장
  15. Cloud Messaging과 Functions을 이용한 푸시메세지 기능 - Functions를 통한 FCM 발송
  16. Cloud Messaging과 Functions을 이용한 푸시메세지 기능 - Service worker를 이용한 FCM수신
  17. Realtime Database 권한 설정

 










728x90