본문 바로가기

UIKIT/Firebase

🔥 Firebase Storage에 이미지 업로드, 이미지 주소 URL 가져오기

func uploadAvatar() {
    let userID = Auth.auth().currentUser?.uid ?? "" // ✅ 유저 ID 가져오기
    guard let imageData = imageData?.jpegData(compressionQuality: 0.5) else { return } // ✅ 이미지 데이터 변환
    let metaData = StorageMetadata() // Firebase Storage 메타데이터 생성
    metaData.contentType = "image/jpeg" // ✅ 파일 타입 설정

    StorageManager.shared.uploadProfilePhoto(with: userID, image: imageData, metaData: metaData)
        .flatMap { metaData in
            StorageManager.shared.getDownloadURL(for: metaData.path) // ✅ 업로드된 이미지의 URL 가져오기
        }
        .sink { [weak self] completion in
            switch completion {
            case .failure(let error): // ✅ 에러 발생 시
                print(error.localizedDescription)
                self?.error = error.localizedDescription
            case .finished: // ✅ 성공 시
                self?.updateUserData() // 유저 데이터 업데이트
            }
        } receiveValue: { [weak self] url in
            self?.avatarPath = url.absoluteString // ✅ URL 저장
        }
        .store(in: &cancelable) // ✅ 메모리 해제 방지
}

 

📌 uploadAvatar()의 전체 흐름

1️⃣ 유저 ID 가져오기 → Firebase Storage에서 유저별 폴더를 만들기 위해 사용.
2️⃣ 이미지를 jpegData(compressionQuality:)로 변환 → Storage에 업로드하기 위해 Data로 변환.
3️⃣ Firebase Storage 메타데이터 설정 → "image/jpeg" 설정하여 이미지 파일임을 명시.
4️⃣ Firebase Storage에 이미지 업로드 → uploadProfilePhoto() 호출.
5️⃣ 업로드된 이미지의 다운로드 URL 요청 → flatMap을 사용해 getDownloadURL() 호출.
6️⃣ sink에서 결과 처리

  • 실패 시 에러 처리.
  • 성공 시 다운로드 URL을 avatarPath에 저장하고, updateUserData() 실행.

 

✅ Firebase Storage 메타데이터 생성

let metaData = StorageMetadata()
metaData.contentType = "image/jpeg"
  • StorageMetadata() → Firebase Storage에 저장할 파일의 정보를 설정하는 객체.
  • metaData.contentType = "image/jpeg" → 파일의 MIME 타입을 지정.
    • "image/jpeg" → 이 파일은 JPEG 이미지임을 Firebase에 알려줌.

📌 💡 왜 contentType을 설정해야 할까?

  • Firebase는 파일의 MIME 타입을 기반으로 올바른 처리를 한다.
  • 예를 들어:
    • "image/png" → PNG 이미지
    • "video/mp4" → MP4 비디오
    • "application/pdf" → PDF 파일
  • 설정하지 않으면 브라우저에서 파일을 다운로드할 때 인식이 안 될 수도 있음.

✅ flatMap을 사용하여 업로드된 이미지의 다운로드 URL 가져오기

.flatMap { metaData in
    StorageManager.shared.getDownloadURL(for: metaData.path)
}
  • uploadProfilePhoto()를 실행하면 Firebase Storage에 이미지가 저장된 후, StorageMetadata를 반환.
  • StorageMetadata.path를 사용해 Firebase에서 해당 이미지의 다운로드 URL을 요청.
  • 즉, 첫 번째 작업(업로드) → 두 번째 작업(다운로드 URL 가져오기)을 연결.

📌 💡 flatMap을 사용하는 이유?

  • uploadProfilePhoto()와 getDownloadURL() 모두 비동기 함수(Publisher) 이므로,
    업로드가 끝난 후 바로 URL을 요청하기 위해 flatMap을 사용.