Skip to content

Comments

Fix(client): service-worker 경로 수정#164

Merged
jllee000 merged 5 commits intodevelopfrom
fix/#161/fcm-setting-edit
Sep 29, 2025
Merged

Fix(client): service-worker 경로 수정#164
jllee000 merged 5 commits intodevelopfrom
fix/#161/fcm-setting-edit

Conversation

@jllee000
Copy link
Collaborator

@jllee000 jllee000 commented Sep 29, 2025

📌 Related Issues

관련된 Issue를 태그해주세요. (e.g. - close #25)

📄 Tasks

  • 서비스워커 기준에서 (온보딩폴더) 경로에 슬래쉬없어서,, 상대 경로로 잡히는 문제!
  • 실제 가리켜야 하는 firebase-messaging 파일은 public에 있어서 / 추가하여 경로 지정 수정

⭐ PR Point (To Reviewer)

📷 Screenshot

Summary by CodeRabbit

  • 신기능
    • 백그라운드 푸시 알림 지원 및 수신 시 시스템 알림 표시
    • Firebase 초기화 구성 추가로 클라이언트 알림 기능 활성화
  • 버그 수정
    • 서비스 워커 등록 경로를 절대경로로 변경하여 등록 실패 감소
  • 작업
    • Firebase SDK를 CDN에서 로드하도록 전환
    • Vercel 리라이트 규칙 추가로 SDK 자산 경로(/firebase_sdk) 정상 제공
  • 스타일
    • 온보딩 화면 관련 코드 포매팅 정리 (로직 변화 없음)

@vercel
Copy link

vercel bot commented Sep 29, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
pinback-client-client Ready Ready Preview Comment Sep 29, 2025 3:39pm
pinback-client-landing Ready Ready Preview Comment Sep 29, 2025 3:39pm

@coderabbitai
Copy link

coderabbitai bot commented Sep 29, 2025

Walkthrough

Firebase 메시징 구성과 서비스 워커 흐름을 조정했다. 퍼블릭에 firebase-config를 추가하고, 서비스 워커를 CDN importScripts 기반으로 전환해 FCM 백그라운드 알림을 처리한다. 서비스 워커 등록 경로를 절대경로로 수정하고, vercel 리라이트에 /firebase_sdk/* 패스스루를 추가했다. 일부 TSX는 서식만 정리했다.

Changes

Cohort / File(s) Summary
Firebase 퍼블릭 설정/서비스워커
apps/client/public/firebase-config.js, apps/client/public/firebase-messaging-sw.js
퍼블릭 firebaseConfig 상수 추가. SW에서 로컬 스크립트 대신 CDN(firebase-app-compat.js, firebase-messaging-compat.js) 로드, Firebase 초기화 및 onBackgroundMessage로 알림 표시. SW install/activate 핸들러 추가.
SW 등록 경로 수정
apps/client/src/pages/onBoarding/utils/registerServiceWorker.ts
등록 경로를 firebase-messaging-sw.js에서 \/firebase-messaging-sw.js로 변경.
라우팅 리라이트
apps/client/vercel.json
rewrites\/firebase_sdk\/(.*) 패스스루 추가 후, catch-all \/(.*) -> /index.html 유지.
서식/정렬 정리
apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx
비교 연산자 공백, trailing comma 등 코드 포맷 정리. 기능 변경 없음.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as Browser
  participant App as Web App
  participant SW as Service Worker (firebase-messaging-sw.js)
  participant FCM as Firebase Cloud Messaging

  User->>App: 방문
  App->>App: registerServiceWorker('/firebase-messaging-sw.js')
  App->>SW: 등록 요청
  activate SW
  SW->>SW: importScripts(CDN firebase-app-compat, firebase-messaging-compat)
  SW->>SW: firebase.initializeApp(firebaseConfig)
  SW->>SW: firebase.messaging()

  FCM-->>SW: Push (background)
  SW->>SW: onBackgroundMessage(payload)
  SW->>User: showNotification(title/body)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

fix

Suggested reviewers

Poem

꼬박꼬박 알림 씨앗 심고, 퐁퐁 솟는 톡톡 소식🌱
나는 토끼, CDN 길 따라 폴짝폴짝 뛰었지.
스워는 깨어 “대기 끝!” 하고,
푸시는 오면 “띵!” 하고.
경로도 반듯, 리라이트도 착!
이제 알림 숲에서 뛰놀 시간이다. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning 링크된 이슈 #161의 FCM 커스텀 연동 수정은 코드 변경으로 적절히 반영되었지만, 디자인 시스템 Progress 컴포넌트 구현(#25)에 대한 작업은 전혀 포함되지 않았습니다. #25 요구사항이 이 PR의 목표와 부합하지 않으므로 해당 이슈를 해결하지 못했습니다. 현재 상태로는 두 이슈 모두 충족되지 않은 것으로 볼 수 있습니다. #25 이슈와 관련된 Progress 컴포넌트 구현을 이 PR에 포함하거나, PR 링크에서 해당 이슈를 분리하여 연결 이슈 목록을 조정하세요. 연결된 이슈 목록을 실제 수행된 작업과 일치시키는 것이 중요합니다. 이 과정을 거치면 PR 목표와 변경 내용이 명확해집니다.
Out of Scope Changes Check ⚠️ Warning apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx 파일에서 수행된 공백 및 포매팅 변경은 FCM 커스텀 연동 수정(#161)과 직접적인 관련이 없습니다. 이와 같은 스타일링 작업은 분리된 포맷팅 전용 PR에서 처리해야 합니다. 현재 상태로는 PR 범위가 불필요하게 넓어져 리뷰 집중도가 분산될 위험이 있습니다. MainCard.tsx의 포매팅 변경을 별도의 PR로 분리하거나 해당 부분을 제거하여 FCM 연동 관련 변경만 포함되도록 정리하세요. 이렇게 하면 PR이 더 명확해지고 리뷰어가 핵심 변경에 집중하기 쉬워집니다. 범위를 좁힌 PR은 관리와 검증이 모두 간편해집니다.
Description Check ⚠️ Warning PR 설명은 Related Issues 섹션만 채워져 있고 Tasks, PR Point, Screenshot 섹션은 템플릿 주석만 남아 있어 실제 내용이 전혀 작성되지 않았습니다. 템플릿의 불필요한 섹션은 제거하거나 실제 작업 내용을 기입해야 합니다. 이 상태로는 리뷰어가 변경 목적과 상세 내용을 파악하기 어렵습니다. Tasks, PR Point, Screenshot 섹션을 제거하거나 실제 작업 요약과 검토 포인트, 필요한 스크린샷을 추가하여 설명을 완성하세요. 관련 이슈나 변경 사항에 대한 자세한 설명을 기재하면 리뷰 효율이 향상됩니다. PR 설명이 명확해지면 승인 과정이 원활해집니다.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed 제목 'Fix(client): service-worker 경로 수정'은 서비스 워커 등록 경로 변경을 정확히 설명하여 주요 변경점 중 하나를 잘 나타냅니다. 제목이 구체적이고 불필요한 단어 없이 명확하게 작성되었습니다. PR 내 다른 변경 사항(예: firebase-config 추가)은 제목에 포함되지 않았지만, 제목이 중요한 수정 사항을 충분히 요약하고 있습니다.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#161/fcm-setting-edit

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

✅ Storybook chromatic 배포 확인:
🐿️ storybook

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

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-config import 경로가 잘못되어 모듈을 찾을 수 없습니다.

현재 파일 위치에서 '../../../../firebase-config'apps/client/src/firebase-config를 가리키지만, 이번 PR에서 추가된 파일은 apps/client/public/firebase-config.js에 있습니다. 이 경로로는 번들러가 모듈을 찾지 못해 빌드가 깨집니다. src 하위로 파일을 옮기거나, tsconfig/vite alias를 정의해 올바른 경로로 불러오도록 조정해주세요.


64-65: React 재렌더마다 initializeApp이 반복 호출됩니다.

함수형 컴포넌트 본문에서 initializeApp을 실행하면 상태 업데이트 등으로 재렌더링될 때마다 호출되어 [DEFAULT] already exists 예외가 터집니다. 모듈 스코프로 올리거나 getApps()를 이용해 이미 초기화됐는지 확인한 뒤 호출하도록 변경해야 합니다.

-import { initializeApp } from 'firebase/app';
+import { initializeApp, getApp, getApps } from 'firebase/app';
...
-const app = initializeApp(firebaseConfig);
+const app = getApps().length ? getApp() : initializeApp(firebaseConfig);
🧹 Nitpick comments (5)
apps/client/src/pages/onBoarding/utils/registerServiceWorker.ts (1)

1-11: SSR/브라우저 지원 가드 추가 및 경고 UI 정리 제안

브라우저 비지원/SSR 환경에서의 예외를 피하고, 실패 시 alert 대신 로깅/관측으로 대체하는 편이 UX에 안전합니다.

 export const registerServiceWorker = () => {
-  navigator.serviceWorker
-    .register('/firebase-messaging-sw.js')
+  if (typeof window === 'undefined' || !('serviceWorker' in navigator)) return;
+
+  navigator.serviceWorker
+    .register('/firebase-messaging-sw.js')
     .then(function (registration) {
-      console.log(`Service Worker 등록 성공:, ${registration}`);
+      console.log('Service Worker 등록 성공:', registration);
     })
     .catch(function (error) {
-      console.log('Service Worker 등록 실패:', error);
-      alert(`Service Worker 등록 실패:, ${error}`);
+      console.error('Service Worker 등록 실패:', error);
+      // TODO: 필요 시 토스트/로깅(Sentry 등)으로 전환
     });
 };
apps/client/public/firebase-messaging-sw.js (4)

25-27: activate 시 즉시 클라이언트 제어

skipWaiting()만으로는 활성화 이후 열린 탭을 즉시 제어하지 못합니다. clients.claim()을 함께 호출하세요.

 self.addEventListener('activate', function () {
-  console.log('실행중..');
+  self.clients.claim();
+  console.log('SW 활성화 완료');
 });

33-41: 알림 클릭 동작 처리 및 payload data 전달

알림 클릭 시 앱 포커스/탭 재사용을 처리하면 UX가 좋아집니다. 또한 payload.datanotification.data로 넘겨 두면 라우팅 등에 활용할 수 있습니다.

 messaging.onBackgroundMessage((payload) => {
   console.log('Received background message ', payload);

   const notificationTitle = payload.notification?.title ?? '알림이 도착했어요!';
   const notificationOptions = {
-    body: payload.notification?.body,
+    body: payload.notification?.body,
+    data: payload.data, // 클릭 시 사용할 데이터 전달
   };
   self.registration.showNotification(notificationTitle, notificationOptions);
 });

+// 알림 클릭 시 기존 탭 포커스 또는 새 창 열기
+self.addEventListener('notificationclick', (event) => {
+  const url = event?.notification?.data?.url || '/';
+  event.notification.close();
+  event.waitUntil(
+    self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientsArr) => {
+      for (const client of clientsArr) {
+        if ('focus' in client) {
+          client.navigate && client.navigate(url);
+          return client.focus();
+        }
+      }
+      return self.clients.openWindow ? self.clients.openWindow(url) : undefined;
+    })
+  );
+});

14-19: Service Worker용 Firebase Messaging compat CDN 버전 업데이트 권장

앱에서 사용 중인 Firebase SDK 버전(예: 10.13.2)에 맞춰 firebase-app-compat.jsfirebase-messaging-compat.js importScripts를 최신 패치로 조정하세요.
예시:

// firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-messaging-compat.js');

공식 문서에 따르면 번들링 없이 Service Worker에서 Firebase Messaging을 사용할 때 compat CDN 번들을 권장하며, 버전 숫자는 앱에 설정된 SDK 버전으로 교체해야 합니다.


4-12: Firebase config 중복 제거 및 storageBucket 값 확인 권장

  • public/firebase-config.js에 이미 동일한 설정이 있으므로, 서비스 워커(firebase-messaging-sw.js)에서도 importScripts('/firebase-config.js')로 불러와 중복을 제거하세요.
  • storageBucket은 프로젝트 콘솔에 표시된 정확한 버킷 이름을 사용해야 합니다. 2024-10-30 이후 생성된 기본 버킷은 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',
-};
+// firebaseConfig는 /firebase-config.js에서 주입
+// 서비스 워커 환경에서도 importScripts로 로드 가능
+importScripts('/firebase-config.js');
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 356dfdb and 61b280c.

📒 Files selected for processing (5)
  • apps/client/public/firebase-config.js (1 hunks)
  • apps/client/public/firebase-messaging-sw.js (2 hunks)
  • apps/client/src/pages/onBoarding/components/funnel/MainCard.tsx (3 hunks)
  • apps/client/src/pages/onBoarding/utils/registerServiceWorker.ts (1 hunks)
  • apps/client/vercel.json (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
apps/client/public/firebase-messaging-sw.js (1)
apps/client/public/firebase-config.js (1)
  • firebaseConfig (1-9)
apps/client/public/firebase-config.js (1)
apps/client/public/firebase-messaging-sw.js (1)
  • firebaseConfig (4-12)
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)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: storybook
🔇 Additional comments (1)
apps/client/src/pages/onBoarding/utils/registerServiceWorker.ts (1)

3-3: 절대 경로 등록 및 파일 위치 확인 완료
apps/client/public/firebase-messaging-sw.js 파일이 존재하므로 /firebase-messaging-sw.js로 올바르게 제공됩니다. 프리뷰/프로덕션 환경에서 실제 제공 여부만 최종 확인해 주세요.

Comment on lines +1 to +9
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',
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

firebaseConfig를 export하지 않으면 빌드가 실패합니다.

이 파일은 오직 상수만 선언하고 내보내지 않아서 MainCard.tsx에서 import { firebaseConfig } 구문이 즉시 컴파일 에러(has no exported member)로 이어집니다. 최소한 명시적으로 export하도록 수정해야 합니다.

-const firebaseConfig = {
+export 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',
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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',
};
// apps/client/public/firebase-config.js
export 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',
};
🤖 Prompt for AI Agents
In apps/client/public/firebase-config.js lines 1 to 9, the file only declares
the firebaseConfig constant but does not export it, causing import errors where
firebaseConfig is imported; modify the file to export the constant (e.g., add an
export statement or export the declaration) so that other modules can import {
firebaseConfig } without compile errors.

@jllee000 jllee000 merged commit 5b2611e into develop Sep 29, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix 버그 수정하라 러브버그

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Fix] FCM 커스텀 및 연동 수정

1 participant