feat: PWA FCM 클라이언트 실통합 + 어댑터 키 주입 런처
- firebase SDK 통합: initPush getToken 활성화(동적 import) + isSupported 가드 - public/firebase-messaging-sw.js 백그라운드 수신 SW(웹 config 쿼리스트링 전달) - run-api-with-adapters.sh: adapter.env.local 로드 후 ga-api bootRun - 키 파일(adapter.env.local / .env.local)은 git-ignored 템플릿으로 별도 제공 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,11 +6,10 @@ import { pushApi } from '@/api/push';
|
||||
* 활성 조건: 빌드 환경변수 `VITE_FCM_*` 가 모두 설정된 경우에만 동작한다.
|
||||
* 미설정 시 no-op (개발/미연동 환경에서 안전).
|
||||
*
|
||||
* <b>운영 활성화 절차</b>:
|
||||
* 1) Firebase 프로젝트 생성 → 웹 앱 등록 → 설정값을 .env 의 VITE_FCM_* 로 주입
|
||||
* 2) `npm i firebase` 후 아래 TODO 블록의 firebase/messaging 초기화 활성화
|
||||
* 3) getToken(VAPID key)으로 FCM 토큰 발급 → pushApi.register(token) 호출
|
||||
* 4) public/firebase-messaging-sw.js 서비스워커 배치
|
||||
* firebase SDK 통합 완료 — 활성 조건은 `.env(.local)` 의 VITE_FCM_* 주입뿐이다.
|
||||
* 1) Firebase 콘솔 → 웹 앱 등록 → 설정값을 .env.local 의 VITE_FCM_* 로 주입
|
||||
* 2) getToken(VAPID key)으로 FCM 토큰 발급 → pushApi.register(token) 자동 호출
|
||||
* 3) public/firebase-messaging-sw.js 가 백그라운드 수신 처리
|
||||
*
|
||||
* 서버측(PushAdapter=fcm + FCM_PROJECT_ID/FCM_ACCESS_TOKEN)과 함께 활성화해야 실제 발송된다.
|
||||
*/
|
||||
@@ -38,14 +37,38 @@ export async function initPush(): Promise<void> {
|
||||
const permission = await Notification.requestPermission();
|
||||
if (permission !== 'granted') return;
|
||||
|
||||
// TODO(운영): `npm i firebase` 후 활성화.
|
||||
// const { initializeApp } = await import('firebase/app');
|
||||
// const { getMessaging, getToken } = await import('firebase/messaging');
|
||||
// const appFb = initializeApp(cfg);
|
||||
// const messaging = getMessaging(appFb);
|
||||
// const token = await getToken(messaging, { vapidKey: cfg.vapidKey });
|
||||
// if (token) await pushApi.register(token, 'WEB');
|
||||
void pushApi; // 등록 API 는 토큰 발급 후 호출 (위 TODO 활성화 시)
|
||||
const { isSupported, getMessaging, getToken } = await import('firebase/messaging');
|
||||
if (!(await isSupported())) {
|
||||
if (import.meta.env.DEV) console.info('[push] 이 브라우저는 FCM 미지원 — skip.');
|
||||
return;
|
||||
}
|
||||
|
||||
const { initializeApp, getApps } = await import('firebase/app');
|
||||
const appFb = getApps().length
|
||||
? getApps()[0]
|
||||
: initializeApp({
|
||||
apiKey: cfg.apiKey,
|
||||
projectId: cfg.projectId,
|
||||
appId: cfg.appId,
|
||||
messagingSenderId: cfg.messagingSenderId,
|
||||
});
|
||||
|
||||
// FCM 백그라운드 수신용 서비스워커 (vite-plugin-pwa SW 와 별개).
|
||||
// 웹 config 는 정적 SW 파일에 박지 않고 쿼리스트링으로 전달.
|
||||
const swQuery = new URLSearchParams({
|
||||
apiKey: cfg.apiKey,
|
||||
projectId: cfg.projectId,
|
||||
appId: cfg.appId,
|
||||
messagingSenderId: cfg.messagingSenderId ?? '',
|
||||
}).toString();
|
||||
const swReg = await navigator.serviceWorker.register(`/firebase-messaging-sw.js?${swQuery}`);
|
||||
|
||||
const messaging = getMessaging(appFb);
|
||||
const token = await getToken(messaging, {
|
||||
vapidKey: cfg.vapidKey,
|
||||
serviceWorkerRegistration: swReg,
|
||||
});
|
||||
if (token) await pushApi.register(token, 'WEB');
|
||||
} catch (e) {
|
||||
if (import.meta.env.DEV) console.warn('[push] init 실패', e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user