← 목록으로
개발일지

카드뽑기 Firebase 카운터 연결

1

카드뽑기 페이지에 붙어있던 카운터 위젯이 Firebase에 연결되지 않고 있던 문제를 발견하고 수정한 날입니다.


카운터가 동작하지 않던 이유

단색 카드뽑기와 그라데이션 카드뽑기 페이지에는
뽑기 횟수를 누적으로 집계하는 cardcounter.js 위젯이 붙어있었습니다.

코드 자체는 완성돼 있었는데, 실제로는 카운트가 전혀 쌓이지 않고 있었습니다.

원인을 보니 cardcounter.jswindow.firebaseDBwindow.firestoreUtils
전역에서 읽어오는 구조인데, 이 두 값을 설정해주는 코드가 아예 없었습니다.

카운터 내부에서는 이 값들이 나타날 때까지 100ms 간격으로 최대 5초를 기다리는 폴링 루프가 돌고 있었는데,
당연히 5초가 지나도 값이 없으니 조용히 실패하고 있었던 겁니다.


구조적으로 왜 빠져있었냐면

Next.js 쪽에는 src/lib/firebase.ts 에서 Firebase를 초기화하고 db 를 export하는 코드가 있습니다.
그런데 카드뽑기 툴은 public/tools/ 아래의 정적 HTML 파일로 돼있어서
Next.js 모듈 시스템을 전혀 거치지 않습니다.

즉 TypeScript 모듈에서 export한 db 를 HTML 파일이 import할 방법이 없는 구조였습니다.


firebase-init.js 추가

public/js/firebase-init.js 를 새로 만들었습니다.

Firebase 웹 SDK를 CDN에서 불러오고 앱을 초기화한 뒤,
window.firebaseDBwindow.firestoreUtils 를 전역에 노출하는 역할입니다.

import { initializeApp, getApps } from 'https://www.gstatic.com/firebasejs/10.14.1/firebase-app.js';
import { getFirestore, doc, getDoc, setDoc, updateDoc, increment }
  from 'https://www.gstatic.com/firebasejs/10.14.1/firebase-firestore.js';

const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];
window.firebaseDB     = getFirestore(app);
window.firestoreUtils = { doc, getDoc, setDoc, updateDoc, increment };

type="module" 스크립트라 브라우저가 파싱 후 지연 실행하는데,
cardcounter.js 의 폴링 루프가 그 사이를 메꿔줍니다.
실제로는 모듈이 실행되고 100~200ms 내에 카운터가 Firebase를 감지합니다.


실행 순서

HTML 파싱
 ├─ <script type="module" src="/js/firebase-init.js">  → 파싱 후 지연 실행으로 대기
 └─ <script src="/components/cardcounter.js">          → 즉시 실행, 함수만 등록

DOMContentLoaded
 └─ initializeCardCounter() 호출
     └─ waitForFirebase() 폴링 시작 (100ms 간격)

모듈 실행 완료
 └─ window.firebaseDB / window.firestoreUtils 설정

폴링 감지 → Firestore card_draws 컬렉션 조회 → 카운터 표시

뽑기 버튼을 클릭하면 onCardDrawn('single' | 'gradient', cardData) 를 호출해
Firestore 문서를 증가시키고 표시를 갱신합니다.


카운터 코드 자체는 멀쩡히 작성돼 있었는데 초기화 연결이 빠진 채로 오래 있었네요.
Firebase 설정값은 이미 저장소에 공개돼있는 클라이언트 키라 별도 보안 처리 없이 바로 사용했습니다.