Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughFCM 서비스워커를 Firebase Messaging 전용 처리로 교체하고, 퍼블릭 firebase 설정 파일과 Vercel rewrites를 추가했습니다. 클라이언트·익스텐션의 Axios 요청 인터셉터는 토큰 갱신/온보딩 리다이렉트 흐름으로 리팩터링되었습니다. 온보딩 UI는 포매팅 변경만 포함됩니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User as 브라우저(SW)
participant FApp as Firebase App (SW)
participant FCM as Firebase Messaging
participant Reg as ServiceWorker Registration
Note over User,FApp: SW 로드
User->>FApp: importScripts + initializeApp(firebaseConfig)
FApp->>FCM: getMessaging()
FCM-->>User: onBackgroundMessage 등록
Note over FCM,Reg: 백그라운드 메시지 수신
FCM->>User: payload 전달
User->>Reg: showNotification(title, options)
sequenceDiagram
autonumber
participant UI as 클라이언트/익스텐션
participant AX as Axios 요청 인터셉터
participant LS as localStorage/Storage
participant Auth as refreshToken/fetchToken
participant API as 서버 API
participant OB as Onboarding Page
UI->>AX: 요청 시작
AX->>LS: email/token 조회
alt 이메일 존재 (클라이언트)
AX->>Auth: refreshToken(email)
alt 성공
Auth-->>AX: 새 토큰
AX->>AX: Authorization 헤더 설정
AX->>API: 요청 진행
else 실패
AX->>LS: 토큰/이메일 삭제
AX->>OB: 리다이렉트
AX-->>UI: 오류 전파
end
else 이메일 없음 또는 NoAuth(익스텐션)
alt isNoAuth
AX->>API: 토큰 없이 진행
else 이메일 없음
AX->>OB: 리다이렉트/에러
AX-->>UI: 오류 전파
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewersPoem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx (2)
13-15: Firebase 설정 모듈 import가 빌드 타임에 실패합니다.
public/firebase-config.js는 번들에 포함되지 않는 정적 에셋이라 ES 모듈 export가 제공되지 않습니다. 따라서import { firebaseConfig } from '../../../../firebase-config';구문은 Vite/TS 컴파일 단계에서 해당 모듈을 찾지 못해 빌드가 깨집니다. React 쪽에서 사용할 설정은src영역에 export 가능한 모듈로 유지하거나,fetch('/firebase-config.js')등 런타임 로딩 방식으로 분리해주세요. 현재 상태로는 온보딩 페이지가 로드되지 않습니다.
64-66:initializeApp를 렌더링 시마다 호출하면 바로 예외가 발생합니다.컴포넌트가 상태 업데이트로 재렌더링될 때마다
initializeApp(firebaseConfig)가 다시 실행되어Firebase App named '[DEFAULT]' already exists (app/duplicate-app)예외가 터집니다. 초기화는 컴포넌트 외부나getApps()가드로 한 번만 수행하도록 바꿔주세요.-import { initializeApp } from 'firebase/app'; +import { getApps, initializeApp, getApp } from 'firebase/app'; … -const app = initializeApp(firebaseConfig); +const app = getApps().length > 0 ? getApp() : initializeApp(firebaseConfig);
🧹 Nitpick comments (5)
apps/client/public/firebase-messaging-sw.js (5)
14-19: importScripts 호출 순서 정리 및 config 선로딩
firebase.initializeApp이전에 config를 로드해야 합니다. 또한 importScripts는 한 번에 여러 URL을 받을 수 있어 가독성이 좋아집니다.적용 diff:
-importScripts( - 'https://www.gstatic.com/firebasejs/9.22.2/firebase-app-compat.js' -); -importScripts( - 'https://www.gstatic.com/firebasejs/9.22.2/firebase-messaging-compat.js' -); +importScripts( + '/firebase-config.js', + 'https://www.gstatic.com/firebasejs/9.22.2/firebase-app-compat.js', + 'https://www.gstatic.com/firebasejs/9.22.2/firebase-messaging-compat.js' +);추가 확인:
/firebase-config.js에서const firebaseConfig = {...}가 전역 바인딩으로 들어오므로 SW 본문에서 바로 참조 가능합니다. 혹시 스코프 이슈가 있으면self.firebaseConfig = {...}로 노출하도록 변경해 주세요.
5-5: Gitleaks 경고(API 키): Firebase Web API Key는 비밀값이 아니지만 방어선은 필요합니다.Firebase Web API Key는 공개되어도 정상 동작을 전제로 하나, 보안을 위해 다음을 권장합니다:
- Firestore/Storage/Functions 규칙 최소권한 설정
- 도메인/앱 제한(가능한 리소스에 한함)
- Gitleaks false-positive 억제(allowlist 패턴 추가) 또는 키 회전 절차 문서화
검증 스텝:
- 콘솔의 보안 규칙/도메인 제한 현황 캡처 공유
- Gitleaks 설정에 Firebase 키 허용 규칙 추가 여부 확인
25-27: activate 단계에 clients.claim() 추가로 즉시 제어권 확보업데이트된 SW가 활성화 즉시 모든 클라이언트를 제어하도록 권장됩니다.
적용 diff:
self.addEventListener('activate', function () { console.log('실행중..'); + self.clients.claim(); });
29-33: initializeApp 중복 초기화 가드드물게 SW 재평가 시 중복 초기화를 방지하세요.
적용 diff:
-firebase.initializeApp(firebaseConfig); +if (!firebase.apps || firebase.apps.length === 0) { + firebase.initializeApp(firebaseConfig); +} -const messaging = firebase.messaging(); +const messaging = firebase.messaging();
33-41: 배경 메시지 처리 보강: data-only/notification 혼용 대응 + 클릭 핸들러 + 로그 정리FCM의 onBackgroundMessage는 주로 data-only 메시지에 발동합니다.
payload.notification이 비어 있을 수 있으니payload.data를 폴백으로 사용하고, 클릭 시 딥링크를 열도록notificationclick핸들러를 추가하세요. 프로덕션에서는 상세 payload 로깅을 피하는 것이 좋습니다.적용 diff(해당 범위 내 수정):
-messaging.onBackgroundMessage((payload) => { - console.log('Received background message ', payload); - - const notificationTitle = payload.notification?.title ?? '알림이 도착했어요!'; - const notificationOptions = { - body: payload.notification?.body, - }; - self.registration.showNotification(notificationTitle, notificationOptions); -}); +messaging.onBackgroundMessage((payload) => { + const notification = payload?.notification || {}; + const data = payload?.data || {}; + const title = + notification.title || data.title || '알림이 도착했어요!'; + const body = notification.body || data.body || ''; + const icon = notification.icon || data.icon || '/icons/icon-192.png'; + const url = + notification.click_action || data.click_action || data.url || '/'; + const tag = data.tag; + + self.registration.showNotification(title, { + body, + icon, + tag, + data: { url }, + }); +});추가(파일 하단 등 임의 위치에 새로 추가):
// 알림 클릭 시 기존 탭 포커스/네비게이션 또는 새 창 오픈 self.addEventListener('notificationclick', (event) => { const url = event.notification?.data?.url || '/'; event.notification.close(); event.waitUntil((async () => { const clientsList = await clients.matchAll({ type: 'window', includeUncontrolled: true }); for (const client of clientsList) { // 이미 열려 있으면 포커스 + 네비게이트 if ('focus' in client) { client.navigate(url); return client.focus(); } } return clients.openWindow(url); })()); });백엔드에서 실제로 "notification" 페이로드를 보내는지, "data-only"를 보내는지 확인해 주세요. 혼용 시 위 로직이 모두 대응합니다.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
apps/client/public/firebase-config.js(1 hunks)apps/client/public/firebase-messaging-sw.js(1 hunks)apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx(3 hunks)apps/client/src/shared/apis/setting/axiosInstance.ts(1 hunks)apps/client/vercel.json(1 hunks)apps/extension/src/apis/axiosInstance.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
apps/client/public/firebase-config.js (1)
apps/client/public/firebase-messaging-sw.js (1)
firebaseConfig(4-12)
apps/client/public/firebase-messaging-sw.js (1)
apps/client/public/firebase-config.js (1)
firebaseConfig(1-9)
apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx (2)
apps/client/src/constants/alarms.ts (1)
AlarmsType(11-15)apps/client/src/pages/onBoarding/utils/formatRemindTime.ts (1)
normalizeTime(1-26)
🪛 Gitleaks (8.28.0)
apps/client/public/firebase-config.js
[high] 2-2: Uncovered a GCP API key, which could lead to unauthorized access to Google Cloud services and data breaches.
(gcp-api-key)
apps/client/public/firebase-messaging-sw.js
[high] 5-5: Uncovered a GCP API key, which could lead to unauthorized access to Google Cloud services and data breaches.
(gcp-api-key)
🔇 Additional comments (1)
apps/client/public/firebase-messaging-sw.js (1)
4-12: storageBucket 형식 검증 완료 — 변경 불필요
Firebase 공식 문서에 따르면 최신 버전에서는PROJECT_ID.firebasestorage.app형식도 지원하므로, 현재pinback-c55de.firebasestorage.app설정은 유효합니다.
| const firebaseConfig = { | ||
| apiKey: 'AIzaSyD3KM0IQ4Ro3Dd2fyAY8fnhE1bQ_NesrBc', | ||
| authDomain: 'pinback-c55de.firebaseapp.com', | ||
| projectId: 'pinback-c55de', | ||
| storageBucket: 'pinback-c55de.firebasestorage.app', | ||
| messagingSenderId: '370851215931', | ||
| appId: '1:370851215931:web:08382b5e57808d29dcba1e', | ||
| measurementId: 'G-847ZNSCC3J', | ||
| }; |
There was a problem hiding this comment.
firebaseConfig 하드코딩/중복 제거: public/firebase-config.js로 단일화하세요.
이미 apps/client/public/firebase-config.js가 존재하는데 SW에 동일 값을 하드코딩하면 드리프트 위험이 큽니다. SW에서는 동일 출처 스크립트를 importScripts('/firebase-config.js')로 불러 재사용하세요.
적용 diff(해당 범위 내 삭제만 포함):
-const firebaseConfig = {
- apiKey: 'AIzaSyD3KM0IQ4Ro3Dd2fyAY8fnhE1bQ_NesrBc',
- authDomain: 'pinback-c55de.firebaseapp.com',
- projectId: 'pinback-c55de',
- storageBucket: 'pinback-c55de.firebasestorage.app',
- messagingSenderId: '370851215931',
- appId: '1:370851215931:web:08382b5e57808d29dcba1e',
- measurementId: 'G-847ZNSCC3J',
-};
+// firebaseConfig는 /firebase-config.js에서 주입됩니다.Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Gitleaks (8.28.0)
[high] 5-5: Uncovered a GCP API key, which could lead to unauthorized access to Google Cloud services and data breaches.
(gcp-api-key)
🤖 Prompt for AI Agents
In apps/client/public/firebase-messaging-sw.js around lines 4 to 12, remove the
hardcoded firebaseConfig object (lines 4–12) and instead import the shared
config script from the same origin; replace the block with
importScripts('/firebase-config.js') and use the firebaseConfig value provided
by that script so the service worker reuses the single source of truth in
apps/client/public/firebase-config.js.
| 'https://www.gstatic.com/firebasejs/9.22.2/firebase-app-compat.js' | ||
| ); | ||
| importScripts( | ||
| 'https://www.gstatic.com/firebasejs/9.22.2/firebase-messaging-compat.js' | ||
| ); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
SDK 버전/호환 API 확인(compat onBackgroundMessage 지원 여부 포함)
- 현재
9.22.2고정. 최신 보안 패치 반영 및compat에서onBackgroundMessage지원 상태를 문서로 재확인해 주세요. 필요 시firebase/messaging/sw(모듈) 전환도 고려.
웹 검색 요청:
🌐 Web query:
- Firebase JS SDK 최신 안정 버전은?
- firebase messaging compat에서 service worker에서의 onBackgroundMessage 지원 여부(공식 문서).
💡 Result:
-
최신 안정 Firebase JS SDK: v12.3.0 (릴리스 노트 기준, 2025-09-18). [1]
-
firebase-messaging compat에서 서비스 워커의 onBackgroundMessage 지원 여부: 지원합니다. 공식 문서에는 service worker에서 importScripts로 firebase-app-compat.js / firebase-messaging-compat.js를 불러와 firebase.messaging()을 사용하고 messaging.onBackgroundMessage(...)를 등록하는 예제가 있습니다. [2]
참고문헌
[1] Firebase JavaScript SDK Release Notes.
[2] Receive messages using Firebase Cloud Messaging — Web (서비스 워커 + compat 예제).
Firebase SDK 버전 상향 및 모듈 전환 검토
- Firebase JS SDK를 9.22.2에서 최신 안정 버전(12.3.0, 2025-09-18 기준)으로 상향 적용하세요.
- firebase-messaging-compat는 service worker에서 onBackgroundMessage를 지원하므로, 현 코드에서도 백그라운드 메시지 처리가 가능합니다.
- 장기적 보안 패치 및 트리 셰이킹, 타입 지원을 위해 모듈형 SDK(
firebase/messaging/sw) 전환을 검토하세요.
🤖 Prompt for AI Agents
In apps/client/public/firebase-messaging-sw.js around lines 15 to 19, the
service-worker is importing Firebase SDK v9.22.2 and the compat messaging
bundle; update the imports to a current stable SDK (e.g., 12.3.0) and either (a)
swap the importScripts URLs to the newer compat bundles so your existing
onBackgroundMessage code continues to work, or (b) migrate the service-worker to
the modular service-worker bundle (firebase/messaging/sw) by replacing the
import with the modular sw script and adapting the messaging API calls to the
modular names and initialization flow; ensure you update any API usage in the
file to match the chosen bundle (compat vs modular) and test background message
handling after the change.
|
✅ Storybook chromatic 배포 확인: |
📌 Related Issues
📄 Tasks
변경 사항
src에서public으로 이동=> Service Worker는 Vite 번들에 포함되지 않기 때문에
src내부 모듈(firebase-config.ts)을 불러올 수 없음=> Firebase SDK도 ESM import가 불가능하여, 공식 권장 방식인 CDN
importScripts를 사용해야 함이를 통해 Service Worker에서 Firebase Messaging 초기화 및 푸시 알림 처리 로직이 정상적으로 동작하도록 수정
⭐ PR Point (To Reviewer)
📷 Screenshot
Summary by CodeRabbit