본문 바로가기
CodeLab/Firebase

Firebase Web 채팅앱 만들기 - Storage를 이용한 파일 전송기능

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





단순 채팅메세지를 넘어 파일을 서로 주고 받을 수 있는 기능을 구현해보겠습니다. Firebase Storage를 활용하게 됩니다  클립버튼을 누르면 파일을 선택을 할 수 있고, 파일을 선택하면, 팝업 모달 창이 뜨면서  파일 전송 현황을 볼 수 있는 프로그레스바가 움직이며, 최종적으로 파일을 다운로드 받을 수 있는 링크정보가 메세지로 전달 됩니다.

  



코드를 시작하기 전 Firebase console 로 들어가서 Storage 메뉴로 들어갑니다.  처음 들어가면 아래와 같은 화면이 나옵니다. 시작하기 버튼을 눌러  주세요. 시작하기 버튼을 눌러야 기본적인 권한이 생성이 되고 Bucket이 생성이 되며 Storage를 사용할 수 있는 상태가 됩니다.


이제 코드를 작성해보겠습니다. 아래의 코드를 추가해주십시오.




위 코드는 채팅방 화면에서 클립모양의 아이콘을 클릭 하면 file 타입의 input 태그를 클릭하게 되고, 파일이 선택되어지면 onAttachFile 메소드가 실행됩니다. 

 파일 첨부 메세지를 보내는 핵심 메소드인  onAttachFile 메소드에 대해서 조금 더 자사하게 살펴보겠습니다.

 메소드의 시작코드는 파일 다운로드 팝업을 띄우게 되어 있습니다.


선택한 파일은 event.target.files 에 데이터가 들어옵니다. 파일을 하나 선택할 뿐이지만 형태는 fileList 객체로 데이터가 들어옵니다. 그렇기때문에 배열처럼 첫번째 인덱스의 파일을 선택하여 파일명 변수에 할당합니다.

var files = event.target.files;
var fileName = files[0].name;

파일을 저장하는 위치는 '/날짜(yyyyMMdd)/방ID/유저UID/파일명' 형태로 되어 있습니다. 파일 저장 경로 중에 날짜를 둔것은 Firebase Functions 기능을 통해서 주기적으로 삭제를 실시하기 위함입니다. 예제 후반부에서 다루어볼 계획입니다.

var path = FirebaseChat.yyyyMMddHHmmsss().substr(0, 8) '/'+this.roomId + '/' + this.auth.currentUser.uid + '/' + fileName;
아래코드가 실질적으로 파일을 저장하는 코드입니다. 아래의 코드 중 ref메소드는 Realtime Database와 비슷하게 저장되는 경로를 의미 합니다. 실질적인 저장은 Google Cloud Storage에 저장이 됩니다.

저장하는 put 메소드는 UploadTask 객체를 반환 합니다. UploadTask 객체로 업로드 관리를 수행할수 있습니다. 
var uploadTask = firebase.storage().ref().child(path).put(files[0]);

UploadTask객체는 'state_changed' 이벤트를 발생시킵니다. 아래의 코드는 'state_changed' 이벤트를 받았을 때 3가지의 콜백 함수를 파라미터로 지정한 코드입니다. 첫번째 콜백함수는 진행 중 수행하는 함수이고, 두번째는 에러가 발생했을때, 세번째는 업로드가 완료됬을 때 수행됩니다.
uploadTask.on('state_changed'cbProgress.bind(this) , cbError.bind(this), cbComplete.bind(this));
진행 중 수행하는 콜백 함수인 cbProgresss를 살펴보면, 프로그래스바의 게이지의 넓이를 조정하게 됩니다.

var cbProgress = function(snapshot){ // 진행 과정
    var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    progressBar.style.width = progress+'%';
}

에러 콜백함수인 cbError을 살펴보면, 사용자에게 에러가 발생하였음을 alert창으로 알리고, 콘솔에 에러내용을 출력합니다.
var cbError = function(error) { // 에러발생
    console.log(error);
    $('#dnModal').modal('close');
    alert('업로드 중 에러가 발생하였습니다.');
}
마지막으로 완료 콜백 함수인 cbComplete 함수를 보면, 팝업 모달창을 닫고, 다운로드 url정보가 담긴 메세지를 채팅방에 메세지를 전송하게 됩니다.
var cbComplete = function() { // 완료
    //프로그레스바 닫기
    $('#dnModal').modal('close');

    //완료 다운로드 링크 메세지 보내기
    this.saveMessages(null, uploadTask.snapshot.downloadURL, fileName);

    //files 리셋
    event.target.value='';
}



Firebase Storage는 무료의 경우 저장용량 5GB,다운로드 크기 하루 1GB, 하루 업로드 20000회, 다운로드 50000회의 제한이 있습니다.  유료 종량제 요금의 경우 이러한 제한은 없지만, 사용한 만큼 비용이 청구됩니다. 

이러한 이유로 Storage는 보안 설정이 중요합니다. 보안 설정을 통해서 접근 권한이나 업로드 용량, 업로드 가능한 파일 타입을 지정할 수 있습니다.

Storage의 기본 보안은 Authentication을 통해서 인증 받은 사람들에게 읽기와 쓰기 권한이 부여되어 있습니다.
프로젝트에서 권한 파일인 storage.rules 파일을 열어보세요. 아래와 같이 입력이 되어 있습니다.




앞서 파일을 저장할 때 '/날짜(yyyyMMdd)/방ID/유저UID/파일명' 형태로 저장하였습니다. 이제 읽기권한은 인증받은 유저 모두에게 권한을 부여하나 쓰기 권한은 본인의 유저UID 경로에만 접근해서 저장할수 있도록 하겠습니다. 그리고 이미지 파일과 zip확장자를 가진 파일만 업로드가 되도록 하고, 용량은 5메가바이트 미만으로 제한하겠습니다.

다음은 푸시메세지 기능을 시작하겠습니다!


챕터 완성 소스  :




  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