서버 없이 AdMob app-ads.txt 올리기 — Firebase Hosting 삽질기 (feat. Node 24 호환성 버그)
플레이스토어에 앱을 출시하고 AdMob으로 광고를 붙이려는데, app-ads.txt를 내 "개발자 웹사이트" 루트에 올리라는 요구사항에 걸렸다. 예전엔 Blogger 커스텀 리다이렉트로 우회했었는데, 이번엔 공식적으로 권장되는 Firebase Hosting으로 해보기로 했다. 과정에서 firebase-tools 신버전의 버그를 만나서 꽤 헤맸는데, 똑같이 겪을 사람들을 위해 정리해둔다.
TL;DR
app-ads.txt는 Play Console에 등록한 "웹사이트" 도메인의 루트에, 라인 그대로의 텍스트 파일로 올라가 있어야 함- 자체 서버 없으면 Firebase Hosting(무료)이 공식 권장 대안 — Google Sites는 크롤링 안 됨
firebase-tools 15.32.1+Node v24.15.0조합에서firebase init이 거의 항상 실패함 (새로 생긴 "Agent Skills Setup" 기능과 설정파일 쓰기가 경쟁 조건으로 충돌)- 우회:
init쓰지 말고.firebaserc/firebase.json을 손으로 만들고 바로firebase deploy deploy도 멈추는 경우가 있었는데, 원인은 프로젝트 폴더가Documents밑에 있었기 때문 — OneDrive 동기화든 백신 실시간 감시든, 아무튼Documents폴더 안에서 파일 I/O가 막히는 증상.C:\dev같은 일반 폴더로 옮기니 바로 해결됨
1. app-ads.txt가 뭐고 왜 필요한가
AdMob/프로그래매틱 광고 생태계에서 "이 앱의 광고 인벤토리를 실제로 이 퍼블리셔가 판매하는 게 맞다"는 걸 검증하기 위한 파일이다. Google 공식 문서 기준:
- 내용 형식 예시:
google.com, pub-실제게시자ID, DIRECT, f08c47fec0942fa0 - 위치: Play Console 앱 등록정보의 "웹사이트" 필드에 적힌 도메인의 루트. 웹사이트가
https://example.com이면 파일은 정확히https://example.com/app-ads.txt에 있어야 함 - Google Sites로는 안 됨(공식 문서에 명시), 24시간~최대 1주일 정도 크롤링/반영 시간이 걸림
자체 서버/홈페이지가 없는 1인 개발자라면 Firebase Hosting을 쓰는 게 지금 기준 가장 깔끔한 선택이다. 이미 앱에 Firebase(Firestore 등)를 쓰고 있다면 새 인프라를 더 만들 필요도 없다.
2. 설치 및 준비
npm install -g firebase-tools
firebase login로그인은 브라우저 창이 뜨고 Firebase 콘솔에 쓰던 구글 계정으로 하면 된다.
3. 문제 발생 — firebase init이 계속 실패함
firebase init hosting으로 Hosting 기능 선택 → public 디렉터리 지정 → SPA rewrite 여부 → GitHub Actions 연동 여부까지 정상적으로 진행되다가, 맨 마지막에:
Error: An unexpected error has occurred.--debug 플래그를 붙여서 다시 돌려보니 원인이 드러났다:
=== Agent Skills Setup
If you are using an AI coding agent, Firebase Agent Skills make it an expert at Firebase.
√ Would you like to install agent skills for Firebase? Yes
i Installing Agent skills in the background...
+ Agent skills installation started
[...]
Error: ENOENT: no such file or directory, open 'C:\...\firebase.json'
at Object.writeFileSync (node:fs:2414:20)
at Config.writeProjectFile (...\firebase-tools\lib\config.js:166:12)
at postInitSaves (...\firebase-tools\lib\commands\init.js:243:12)버전 정보 (이 글 기준):
firebase-tools15.32.1- Node.js v24.15.0
- Platform: Windows (win32)
firebase-tools 15.32.1에 새로 생긴 "Agent Skills Setup"(AI 코딩 에이전트용 스킬을 백그라운드로 설치해주는 기능)이 끝나자마자, CLI 본체가 firebase.json을 쓰려는 타이밍과 겹치면서 파일 쓰기가 깨지는 것으로 보인다. "Would you like to install agent skills?"에 No로 답해도 똑같은 자리에서 에러 종류만 바뀌어서(EBADF: bad file descriptor, write) 또 실패했다 — 즉 선택지 문제가 아니라, 경쟁 조건(race condition)성 버그로 보인다. 실제로 재시도할 때마다 성공/실패가 갈렸다(한 번은 우연히 성공하기도 했다).
Node.js가 아주 최신 버전(v24)이라
firebase-tools가 아직 완전히 검증하지 못한 조합일 가능성도 있다. 이 글을 나중에 보는 사람은 그 사이 양쪽 버전이 올라가서 이미 고쳐졌을 수도 있으니, 겪고 있는 증상이 다르면 버전부터 맞춰보는 걸 권한다.
우회 방법 — init 쓰지 말고 설정 파일을 직접 작성
init의 문제 지점(postInitSaves)을 아예 타지 않도록, deploy에 필요한 두 파일을 손으로 만들었다.
.firebaserc:
{
"projects": {
"default": "프로젝트ID"
}
}firebase.json:
{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
}(rewrites로 모든 경로를 index.html로 보내도, public/app-ads.txt처럼 실제로 존재하는 파일은 Firebase Hosting이 rewrite보다 먼저 서빙하기 때문에 app-ads.txt 호스팅과 충돌하지 않는다.)
Windows에서 파일 만들 때 탐색기로 하면 firebase.json.txt처럼 확장자가 숨어서 꼬이는 경우가 많아서, cmd/PowerShell에서 바로:
notepad .firebaserc
notepad firebase.json로 만드는 걸 추천한다. (메모장이 "파일이 없습니다. 새로 만드시겠습니까?"라고 물어보면 예 → 내용 붙여넣기 → 저장)
4. 두 번째 문제 — 이번엔 deploy가 멈춤
설정 파일을 수동으로 만들고 firebase deploy --only hosting을 돌렸는데, 이번엔 다음 지점에서 그냥 멈췄다(에러도 안 뜨고 진행도 안 됨):
i hosting[프로젝트ID]: found 3 files in public
[hosting] uploading with 200 concurrency
[hosting] hash cache [...] not populated
Checked if tokens are valid: true, ...이 뒤로 네트워크 요청 로그(>>> [apiv2])가 아예 안 찍히는 게 특징이었다 — 즉 서버 통신 전에, 로컬 파일 해시 계산 단계에서 멈춘 것. 파일 3개 해시하는 데 멈출 이유가 없으니 네트워크 문제가 아니라 파일 시스템 접근 문제로 의심했다.
프로젝트 폴더 경로가 C:\Users\...\Documents\...였던 게 걸려서, OneDrive 동기화나 Windows Defender 실시간 감시가 파일 접근을 지연/차단하고 있을 가능성을 테스트했다:
New-Item -ItemType Directory -Path C:\dev -Force
Copy-Item -Path "C:\Users\...\Documents\프로젝트폴더" -Destination "C:\dev\프로젝트폴더" -Recurse
cd C:\dev\프로젝트폴더
firebase deploy --only hostingC:\dev 밑으로 옮기자마자 바로 성공했다.
+ hosting[프로젝트ID]: file upload complete
i hosting[프로젝트ID]: finalizing version...
+ hosting[프로젝트ID]: version finalized
i hosting[프로젝트ID]: releasing new version...
+ hosting[프로젝트ID]: release complete
+ Deploy complete!
Hosting URL: https://프로젝트ID.web.app결론: Windows에서 Documents 폴더(특히 OneDrive 연동 계정)는 CLI 도구 작업 폴더로 쓰지 말 것. C:\dev 처럼 동기화/백신 감시가 덜 걸리는 평범한 경로를 쓰는 게 여러모로 안전하다.
5. app-ads.txt 올리고 마무리
notepad public\app-ads.txtgoogle.com, pub-실제게시자ID, DIRECT, f08c47fec0942fa0firebase deploy --only hosting마지막으로 Play Console → 스토어 등록정보 → 연락처 세부정보 → 웹사이트에 https://프로젝트ID.web.app를 정확히 입력(끝에 슬래시나 경로 없이, 발급된 도메인 그대로). 이게 app-ads.txt가 있는 도메인과 정확히 일치해야 AdMob 크롤러가 찾아간다.
같은 Firebase Hosting에 개인정보처리방침 페이지(public/privacy.html)도 같이 올려두면, 플레이스토어가 요구하는 "개인정보처리방침 URL"까지 한 번에 해결된다.
6. 요약 — 전체 명령어 모음
# 설치 및 로그인
npm install -g firebase-tools
firebase login
# (firebase init은 이 시점 버전 조합에서 불안정했음 — 아래로 대체)
# .firebaserc, firebase.json을 수동 작성 후,
# 반드시 OneDrive/백신 감시가 없는 일반 폴더(예: C:\dev)에서 작업
cd C:\dev\내프로젝트
firebase deploy --only hosting| 증상 | 원인 | 해결 |
|---|---|---|
firebase init 끝에서 "Unexpected error" |
Agent Skills Setup과 설정파일 쓰기의 경쟁 조건 (firebase-tools 15.32.1 / Node 24 조합) | init 대신 .firebaserc/firebase.json 수동 작성 |
firebase deploy가 해시 계산 단계에서 멈춤 |
작업 폴더가 Documents(OneDrive/백신 감시) 밑에 있음 |
C:\dev 등 평범한 경로로 폴더 이동 |
| app-ads.txt를 AdMob이 못 찾음 | Play Console 웹사이트 필드와 실제 호스팅 도메인 불일치 | 둘을 정확히 일치시키고 최대 1주일 대기 |
댓글 없음:
댓글 쓰기