[Firebase 웹] 파이어베이스 스토리지 이미지 업로드 및 링크 가져오기

2022. 7. 9. 23:27Firebase

728x90

이번 포스트에서는 파이어베이스 스토리지에 이미지를 업로드하고 해당 링크를 받아오는 방법까지 함께 진행을 해보겠습니다. 

 

파이어베이스 스토리지 (Firebase Storage) 란?

파이어베이스 스토리지는 클라우드에 호스팅 되는 확장 가능한 파일  저장소로 이미지, 텍스트, 오디오, 동영상 파일 등을 저장할 수 있습니다. 파이어베이스 스토리지에 저장되는 파일들도 결국에는 구글 스토리지 API 를 통해 접근할 수 있기 때문에 AWS의 S3 저장소의 구글 버전 정도로 볼 수 있습니다. 보통 이런 파일 저장소에 파일을 저장해 두고 해당 파일을 조회 또는 다운로드할 수 있는 주소를 받아서 데이터베이스, 즉 파이어스토어에 저장해두는 방식을 많이 사용하고 있습니다.

 


1. 초기 세팅하기

그럼 본격적으로 이미지를 업로드하기 앞서 파이어베이스 프로젝트를 하나 만들어 보겠습니다. 프로젝트 세팅하는 방법을 아직 잘 모르시겠다면 이전에 올린 포스트를 참고해주시길 바랍니다.

 

 

[Firebase 웹] 파이어베이스 시작하기 - 웹 앱 초기설정

이번 포스트에서는 파이어 베이스에서 새 프로젝트를 생성하는 방법에 대해 알아보겠다. 마침 관리자 페이지를 만들어야하기 때문에 앞으로 Firebase 관련 예제는 React로 작성을 해보겠다. 일단

mingeesuh.tistory.com

 

 


 

2. 파이어베이스 스토리지 규칙 설정하기

 

위 포스트의 방식대로 초기 세팅을 완료하셨다면 다음으로는 파이어베이스 스토리지에 파일을 업로드하고 조회할 수 있는 권한을 세팅해줘야 합니다.

 

파이어베이스에서 이 권한을 규칙(firebase rules)이라고 하기 때문에 콘솔에 접속하셔서 스토리지 -> Rules로 이동하시거나 CLI를 사용해서 기존 권한을 변경해주시면 됩니다. 아래 예시에서는 CLI를 사용해서 규칙을 변경해보도록 하겠습니다.

 

npm i firebase-tools // 파이어베이스 CLI 관련 툴 패키지 설치 안되어있을시 설치

firebase login // 파이어베이스 프로젝트 생성한 계정으로 로그인 (로그인 할수 있는 창이 뜸)
firebase init // 파이어베이스 프로젝트 초기 설정

 

초기 설정을 진행하기 위해 몇 가지 옵션을 선택해야 하는데 지금은 스토리지만 사용할 것이기 때문에 아래와 같이 스토리지만 선택해주겠습니다. (스페이스바로 선택)

 

>> Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection)

 ◯ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ◯ Firestore: Configure security rules and indexes files for Firestore
 ◯ Functions: Configure a Cloud Functions directory and its files
 ◯ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ◯ Hosting: Set up GitHub Action deploys
❯ ◉ Storage: Configure a security rules file for Cloud Storage
 ◯ Emulators: Set up local emulators for Firebase products

 

이후에는 새로운 프로젝트를 만들어서 연결한 건지 기존에 만들어진 프로젝트를 연결할 건지 물어보는데 이미 프로젝트를 생성하셨다면 아래와 같이 선택하신 후 생성하신 프로젝트 이름을 선택해주시고 나머지는 다 기본 세팅으로 enter를 누르시면 됩니다.

 

Please select an option: 
❯ Use an existing project 
  Create a new project 
  Add Firebase to an existing Google Cloud Platform project 
  Don't set up a default project 

 

그럼 따로 파일 이름을 변경하지 않으셨다면 프로젝트의 루트에 storage.rules라는 파일이 생길 텐데 확인해보시면 아래와 유사한 코드가 있을 것입니다.

 

storage.rules

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth!=null;
    }
  }
}

 

보안 규칙에 대한 작동 방식에 자세하게 알고 싶으시다면 해당 문서를 참고해주길 바랍니다.

현재는 경로와 상관없이 인증된 사용자라면 읽고 쓰기가 가능하도록 설정되어 있는 상태입니다. 이번 예시에서는 인증을 구현하지 않을 것이기 때문에 아래와 같이 인증하지 않은 모든 사용자가 이미지를 업로드하고 조회할 수 있도록 아래와 같이 수정을 해주겠습니다.

 

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true;
    }
  }
}

 

해당 규칙이 적용될 수 있도록 아래 명령어를 입력해서 배포까지 해주도록 하겠습니다.

 

firebase deploy --only storage

3.  업로드 코드 작성하기 ( feat. React)

 

그럼 이제 여러 개의 이미지 파일을 업로드하는 로직을 React로 구현을 해보겠습니다. React를 잘 모르셔도 firebase/storage 에서 불러온 메서드들을 어떤 식으로 사용하는지만 주의 깊게 보시길 바랍니다.

 

import { useState } from "react";
import { storage } from "./api/firebase";
import { ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";
import { Line } from "rc-progress";

const App = () => {
  const [files, setFileList] = useState([]); // 파일 리스트
  const [isUploading, setUploading] = useState(false); // 업로드 상태
  const [photoURL, setPhotosURL] = useState([]); // 업로드 완료된 사진 링크들
  const [progress, setProgress] = useState(0); // 업로드 진행상태

  // 파일 선택시 파일리스트 상태 변경해주는 함수
  const handleImageChange = (e) => {
    for (const image of e.target.files) {
      setFileList((prevState) => [...prevState, image]);
    }
  };

  // 업로드시 호출될 함수
  const handleImageUpload = async (e, fileList) => {
    e.preventDefault();
    try {
      setUploading(true);
      // 업로드의 순서는 상관없으니 Promise.all로 이미지 업로드후 저장된 url 받아오기
      const urls = await Promise.all(
        fileList?.map((file) => {
         // 스토리지 어디에 저장되게 할껀지 참조 위치를 지정. 아래와 같이 지정해줄시 images 폴더에 파일이름으로 저장
          const storageRef = ref(storage, `images/${file.name}`);
          
          // File 또는 Blob 타입일 경우 uploadBytes 또는 uploadBytesResumable 메소드를 사용
          // 만약 base64 또는 data_url 문자열로 업로드를 진행할 경우는 uploadString 사용
          // 자세한 내용은 https://firebase.google.com/docs/storage/web/upload-files 공식문서 참고
          const task = uploadBytesResumable(storageRef, file);
          
          // 업로드 진행률을 모니터링, 업로드 진행률 퍼센트로 상태 지정
          task.on("state_changed", (snapshot) => {
            setProgress(
              Math.round(
                (snapshot.bytesTransferred / snapshot.totalBytes) * 100
              )
            );
          });
          return getDownloadURL(storageRef);
        })
      );
      // 업로드된 이미지 링크 상태로 지정 (보통은 해당 링크를 데이터베이스(파이어스토어)에 저장)
      setPhotosURL(urls);
      alert("성공적으로 업로드 되었습니다");
    } catch (err) {
      console.error(err);
    }
    // 초기화
    setProgress(0);
    setUploading(false);
  };

  return (
    <div>
      <form onSubmit={(e) => handleImageUpload(e, files)}>
		{/* rc-progress의 Line 컴포넌트로 파일 업로드 상태 표시 */}
        <Line percent={progress} strokeWidth={4} strokeColor="#ff567a" />
        <label>
          파일:
          <input
            multiple
            accept="image/*"
            type="file"
            onChange={handleImageChange}
          />
        </label>
        <button type="submit">{isUploading ? "업로드중..." : "업로드"}</button>
      </form>
      {photoURL?.length > 0 && (
        <ul>
          {photoURL.map((url, index) => (
            <li key={index}>
              <img
                src={url}
                alt="사용자 첨부 이미지"
              />
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default App;

 

 

 

이런 식으로 비교적 간단하게 이미지를 포함한 다양한 파일들을 스토리지에 업로드할 수 있습니다. 해당 예시에서는 getDownloadURL 메서드를 사용해 이미지가 저장된 링크를 받아와 화면에 보여주기만 했지만 실제로는 해당 링크를 파이어스토에 저장해 둔 뒤 필요할 때 불러와서 사용하는 게 일반적입니다. 파이어스토어에 데이터를 쓰는 방법은 이전에 작성한 포스트를 참고해주길 바랍니다.

 

 

[Firebase 웹] 파이어스토어에서 데이터 불러오고 쓰기 feat. React

​​이번 포스트에서는 파이어 베이스의 파이어 스토어(firestore) 사용법에 대해 알아보도록 하자. 파이어 베이스에 대한 포스트를 아직 읽지 않았다면 한번 보고 오길 바란다. 2022.02.21 - [Firebase]

mingeesuh.tistory.com

 

 


마지막으로 업로드가 성공적으로 진행이 되는지 확인해보도록 하겠습니다.

 

정상적으로 이미지가 첨부되는걸 확인할수 있습니다.
콘솔에서 Storage를 클릭해봐도 정상적으로 이미지가 업로드된걸 확인할수 있습니다.