Firebase permission-denied 오류 해결: Firestore Rules 체크리스트에서 먼저 확인할 것
Firebase permission-denied 오류는 Firestore Security Rules가 모바일/웹 클라이언트 요청을 거부했다는 뜻입니다. 인증 상태, match 경로, read/write 조건, 쿼리 제약, Rules publish 여부와 프로젝트 ID를 순서대로 확인해야 합니다.
증상부터 정확히 보기

Firebase permission-denied를 만났을 때 먼저 볼 것은 어떤 Firestore 요청이 거부됐는지입니다. 단일 문서 조회인지, 컬렉션 쿼리인지, create/update/delete 중 무엇인지에 따라 필요한 Rules 조건과 클라이언트 쿼리가 달라집니다.
입문 단계에서는 문제를 빨리 없애려고 가장 강한 해결책부터 붙이기 쉽습니다. 하지만 그렇게 처리하면 다음 화면에서 비슷한 문제가 반복됩니다. 작은 재현 코드로 줄이고, 어떤 값이 어느 시점에 바뀌는지 확인하는 편이 더 안전합니다.
왜 이런 문제가 생기는지
이 문제의 중심에는 Firestore Rules가 요청 전체를 허용하거나 거부하는 방식이 있습니다. Rules는 필터가 아니므로, 쿼리가 규칙상 허용되지 않은 문서를 포함할 가능성이 있으면 실제 결과에 그런 문서가 없더라도 요청이 실패할 수 있습니다.
특히 Firestore Rules 작업에서는 request.auth, 문서 경로, resource.data와 request.resource.data, 쿼리의 where 조건, 배포 대상 프로젝트가 함께 영향을 줍니다. 먼저 에러가 나는 경로와 현재 로그인 UID를 확인한 뒤 Rules 조건과 같은 제약을 클라이언트 코드에 넣었는지 비교합니다.
실제 코드에서 고치는 방법
수정은 문제를 가장 작게 재현한 뒤 적용하는 것이 좋습니다. 아래 예시는 실제 프로젝트 코드 전체가 아니라, 확인해야 할 핵심만 남긴 형태입니다.
rules_version = '2';
service cloud.firestore { match /databases/{database}/documents { match /posts/{postId} { allow read: if true; allow write: if request.auth != null; } }
}
위 예시는 공개 읽기는 허용하고 쓰기는 로그인 사용자에게만 허용합니다. 실제 서비스에서는 여기서 끝내지 말고 작성자 UID, 역할, 문서 상태 같은 조건을 추가해야 합니다. 예를 들어 본인 문서만 읽게 하려면 Rules의 request.auth.uid 조건과 클라이언트 쿼리의 where("authorId", "==", user.uid) 제약이 함께 맞아야 합니다.
수정 후 확인할 체크리스트
수정 후에는 Rules 탭에서 Publish가 끝났는지, 앱의 Firebase projectId가 예상한 프로젝트인지, 로그인 상태가 준비된 뒤 Firestore를 호출하는지 확인합니다. 컬렉션/문서 경로와 Rules의 match 경로가 한 글자라도 다르면 같은 오류가 반복됩니다.
체크할 순서는 간단합니다. 먼저 재현 조건이 사라졌는지 확인하고, 그 다음 같은 패턴이 다른 파일에 남아 있는지 봅니다. 마지막으로 임시 회피 코드가 남아 있지 않은지 정리합니다.
마무리 점검
Firebase permission-denied는 한 가지 정답 코드보다 원인을 좁히는 순서가 더 중요합니다. 공식 문서의 Cloud Firestore Security Rules 시작하기, Rules 조건 작성, 쿼리와 Rules 관계, Rules 테스트를 기준으로 인증, 경로, 조건, 쿼리 제약, 배포 프로젝트를 차례대로 확인하세요.
실제 에러 메시지
Firestore Rules 문제는 브라우저 콘솔이나 Firebase SDK 응답에서 보통 아래처럼 보입니다.
FirebaseError: Missing or insufficient permissions.
code: "permission-denied"
먼저 인증 여부를 확인하는 코드
import { getAuth, onAuthStateChanged } from 'firebase/auth';
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (!user) {
console.log('로그인되지 않은 상태입니다.');
return;
}
console.log('uid:', user.uid);
});
Firestore Rules 예시
로그인 사용자만 읽기/쓰기 허용
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{docId} {
allow read, write: if request.auth != null;
}
}
}
본인 문서만 접근 허용
match /users/{userId} {
allow read, update: if request.auth != null
&& request.auth.uid == userId;
}
공개 읽기, 로그인 사용자만 작성
match /posts/{postId} {
allow read: if true;
allow create: if request.auth != null;
allow update, delete: if request.auth != null
&& request.auth.uid == resource.data.authorId;
}
배포했는데도 안 바뀔 때 체크리스트
- Firebase Console에서 Rules가 실제로 Publish 되었는지 확인합니다.
- 앱이 바라보는 Firebase projectId가 운영 프로젝트와 같은지 확인합니다.
- 컬렉션/문서 경로가 Rules의
match경로와 일치하는지 확인합니다. - 로그인 직후 요청이라면 auth state가 준비되기 전에 Firestore를 호출하지 않았는지 확인합니다.
- Emulator를 쓰는 중이면 로컬 emulator rules와 배포 rules를 혼동하지 않았는지 확인합니다.
Firestore permission-denied FAQ
로그인했는데도 permission-denied가 납니다. 왜 그럴까요?
로그인 여부만 확인하는 rules가 아니라 uid, role, 문서 소유자 조건까지 걸려 있을 수 있습니다. request.auth.uid와 문서의 owner 필드가 실제로 같은지 확인하세요.
Rules를 바꿨는데 바로 반영되나요?
Publish가 끝나면 보통 빠르게 반영됩니다. 계속 안 되면 다른 Firebase 프로젝트에 배포했거나 앱 환경변수가 다른 프로젝트를 가리키는 경우가 많습니다.
개발 중에는 모든 접근을 열어도 되나요?
테스트 목적으로 잠깐 열 수는 있지만 운영 프로젝트에서는 위험합니다. 가능하면 Firebase Emulator에서 느슨한 rules를 시험하고 운영 rules는 최소 권한으로 유지하세요.
“Firebase permission-denied 오류 해결: Firestore Rules 체크리스트”에 대한 1개의 생각