Firebase Storage 이미지 오류 해결: 403·404·token·Rules 확인법

··설명 약 7분·작성: 해비·블로그 소개

Firebase Storage 이미지의 403·404와 token·Rules 문제는 어떻게 구분하나요?

Firebase 이미지 오류는 객체 경로·존재 여부·HTTP 상태·접근 방식을 먼저 봅니다. 없는 파일과 권한 실패는 다릅니다. SDK 요청과 token 공유 링크를 구분하며 Rules 변경만으로 기존 링크가 즉시 회수된다고 가정하지 않습니다.

적용 조건·범위: 같은 다운로드 URL을 여는 검사와 getDownloadURL을 새로 호출하는 검사는 구분합니다. 전자는 링크의 유효성, 후자는 SDK 요청의 권한에 영향을 받습니다. Firebase Console에서 버킷 이름을 복사하되 .appspot.com을 무조건 붙이지 마세요. 새 버킷은 .firebasestorage.app 형식일 수 있습니다. 플랜·할당량 문제는 공식 오류 코드와 해당 프로젝트 상태로 확인합니다.

본문 근거: firebase.google.com/docs/storage/web/download-files · firebase.google.com/docs/storage/web/handle-errors · firebase.google.com/docs/storage/web/start

학습 목표와 사전 지식

목표: Storage 이미지의 객체 경로·다운로드 링크·권한 실패를 구분합니다.
사전 지식: Storage ref, 개발자 도구, Firebase Console의 파일 목록

이미지가 깨지면 DB의 문자열을 임의로 고치기 전에 bucket과 객체 경로를 확인하세요. SDK로 얻은 다운로드 URL과 인증된 객체 요청은 보안 의미가 다릅니다.

증상 확인할 사실 수정 위치
404 / object-not-found 객체가 실제로 존재하는가 DB의 storagePath·업로드 완료 처리
403 / unauthorized SDK 인증·Rules 또는 다운로드 token이 유효한가 인증/Rules 또는 링크 재발급
새 탭 성공·fetch 실패 동일 URL의 CORS 응답인가 bucket CORS
업로드는 됐으나 DB 저장 실패 고아 객체가 남았는가 업로드 후 보상 정리 작업

src/images.js · 전체 모듈; 초기화된 storage와 저장된 경로를 전달

import { getDownloadURL, ref } from 'firebase/storage';

export async function resolveImage(storage, storagePath) {
  if (!storagePath) throw new Error('객체 경로가 필요합니다.');
  return getDownloadURL(ref(storage, storagePath));
}

404 최소 재현과 수정

개발 bucket에서 products/demo/cover.png를 업로드한 뒤 경로 products/demo/missing.png로 조회하면 없는 객체 오류가 납니다. src/images.js에 전달하는 DB storagePath를 실제 업로드 결과의 snapshot.ref.fullPath로 저장하도록 수정합니다. 같은 객체 경로로 다시 조회해 URL 취득과 이미지 표시를 확인합니다. 슬래시가 포함된 경로를 직접 URL에 이어 붙이는 대신 ref와 getDownloadURL을 사용하세요.

Storage 오류 구분: 403 권한, 404 경로, token URL

다운로드 token은 공유 링크의 일부입니다

getDownloadURL로 얻은 token URL은 링크를 가진 사람이 접근 가능한 공유 링크로 다뤄야 합니다. 장기 비공개 파일에 URL을 배포하고 Rules만 변경하면 즉시 회수된다고 가정하지 마세요. token을 회전·제거한 경우 기존 링크를 다시 열어 거부되는지 확인하고 DB의 링크를 갱신합니다. 로그·분석 이벤트에 전체 token URL을 남기지 않습니다. 비공개 읽기는 인증 SDK getBlob/getBytes와 Rules, 또는 별도 서버 전달 구조를 검토하세요.

403 수정 전 확인

같은 다운로드 URL을 여는 검사와 getDownloadURL을 새로 호출하는 검사는 구분합니다. 전자는 링크의 유효성, 후자는 SDK 요청의 권한에 영향을 받습니다. Firebase Console에서 버킷 이름을 복사하되 .appspot.com을 무조건 붙이지 마세요. 새 버킷은 .firebasestorage.app 형식일 수 있습니다. 플랜·할당량 문제는 공식 오류 코드와 해당 프로젝트 상태로 확인합니다.

Storage 오류 구분 해결: 파일 경로, Rules, 다운로드 URL

파일 삭제와 DB 정합성

새 이미지 업로드 성공 → 새 경로 DB 반영 → 이전 객체 정리 순으로 나눕니다. Firestore와 Storage를 묶는 원자적 트랜잭션은 없습니다. 중간 실패를 기록하고 재시도할 수 있어야 하며, 삭제 함수에 사용자가 준 임의 URL을 그대로 넘기지 않도록 허용 경로와 권한을 검사하세요.

같은 객체를 세 경로로 진단하기

오류 화면만 보고 Rules를 넓히기 전에 개발 환경에서 bucket·storagePath·인증 상태를 적고, 동일한 객체를 아래 순서로 확인하세요. URL 전체에는 다운로드 token이 들어갈 수 있으므로 로그나 문제 제보에 붙이지 않습니다.

  1. Firebase Console의 정확한 bucket에서 저장된 storagePath의 객체가 있는지 확인합니다. 업로드 코드가 남긴 snapshot.ref.fullPath와 DB 경로를 비교합니다.
  2. 로그인 완료 후 src/images.js의 resolveImage(storage, storagePath)를 호출하고 성공 여부 또는 error.code만 기록합니다. storage/object-not-found는 경로·객체를, storage/unauthorized는 인증·Rules를 확인할 출발점입니다.
  3. SDK가 반환한 동일한 URL을 새 탭과 페이지의 fetch에서 각각 시험합니다. 새 탭에서 열리지만 fetch가 CORS 오류로 막히면, URL 경로를 고치거나 Rules를 완화하기 전에 응답의 Access-Control-Allow-Origin과 bucket CORS 설정을 확인합니다. img 태그 표시와 fetch의 읽기 권한도 동일한 검사로 취급하지 않습니다.
관찰 우선 확인 아직 결론 내릴 수 없는 것
Console에 객체가 없고 SDK가 object-not-found 업로드 완료 여부·DB storagePath Rules가 원인이라고 단정할 수 없음
객체가 있고 SDK가 unauthorized 현재 사용자 UID·get 허용 규칙·bucket 기존 token URL의 유효성과 별개
SDK URL 발급은 성공, 기존 링크만 실패 저장된 링크의 token 변경·만료와 실제 객체 객체 경로를 임의로 바꿀 근거가 아님
동일 링크가 탭에서는 열리고 fetch에서 CORS 오류 브라우저 네트워크 응답과 bucket CORS 파일이 삭제됐다고 단정할 수 없음

스스로 확인하기: A 사용자의 SDK 조회가 거부되는데 과거 token URL은 열립니다. 어느 경로를 먼저 점검해야 할까요? SDK의 인증·Rules와 공유 링크의 token은 다른 접근 방식입니다. token 링크를 공개하지 말고 해당 파일의 의도한 공유 범위부터 결정하세요. 이 절차의 실제 bucket 요청은 편집 환경에서 실행하지 않았습니다.

직접 확인할 결과

실제/없는 경로 각각 SDK 조회
링크 재발급 전후 기존 URL 확인
로그아웃 SDK 접근과 token URL 접근 별도 확인

사용 전 플랜 확인

2026-09-13 공식 문서 기준 Cloud Storage for Firebase는 기본 버킷 접근을 포함해 Blaze 종량제 플랜이 필요합니다. 무료 사용량과 결제 플랜은 다른 개념입니다. 개발 프로젝트의 결제 연결·예산 알림·실제 사용량을 확인하세요.

검증 범위와 기준일

공식 문서 확인일: 2026-09-13. 웹 SDK 예제는 모듈형 API 기준입니다. 이 글의 코드·구조 정적 검토와 실제 클라우드 인증·저장·배포 검증을 구분합니다. 본인 개발 Firebase 프로젝트의 실제 인증·권한·배포 요청은 이 편집 환경에서 실행하지 않았습니다.

이어서 학습하기

공식 문서

이 글이 도움이 되었나요?

조회 중

읽음 기록

읽음 — / 전체 20개 · 필수 14개

이 글을 쓴 해비

웹사이트를 제작·운영하고, 개인 서비스와 자동화·AI 도구를 만듭니다. 직접 만들며 배운 내용과 문제 해결 과정을 BlogFlow에 기록합니다.

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기