React

웹 푸시 구현 예제

패키지 설치

npm install @nativify/notifications firebase

Custom Hook 생성

1단계 useNotification.js

// hooks/useNotification.js import { useState, useEffect, useCallback } from 'react'; import { getNotificationService } from '@nativify/notifications'; export function useNotification() { const [service, setService] = useState(null); const [notifications, setNotifications] = useState([]); const [token, setToken] = useState(null); const [permission, setPermission] = useState('default'); // Firebase 설정 const initFirebase = useCallback(() => { window.firebaseConfig = { apiKey: process.env.REACT_APP_FIREBASE_API_KEY, authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN, projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID, storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID, appId: process.env.REACT_APP_FIREBASE_APP_ID, vapidKey: process.env.REACT_APP_FIREBASE_VAPID_KEY }; }, []); // 메시지 수신 처리 const handleMessage = useCallback((message) => { setNotifications(prev => [{ id: Date.now(), title: message.notification?.title || '알림', body: message.notification?.body || '', timestamp: new Date() }, ...prev]); }, []); // 서비스 초기화 useEffect(() => { const initialize = async () => { try { initFirebase(); const notificationService = getNotificationService(); await notificationService.initialize(); // 메시지 리스너 등록 notificationService.onMessageReceived(handleMessage); setService(notificationService); } catch (error) { console.error('초기화 실패:', error); } }; initialize(); return () => { if (service) { service.onMessageReceived(null); } }; }, [initFirebase, handleMessage]); // 권한 요청 const requestPermission = useCallback(async () => { if (!service) return; try { const perm = await service.requestPermission(); setPermission(perm); if (perm === 'granted') { const fcmToken = await service.getToken(); setToken(fcmToken); console.log('FCM Token:', fcmToken); // 서버에 토큰 등록 await service.registerUserToken( 'delivery_app_001', 'user123', 'https://your-server.com/api/notifications' ); } } catch (error) { console.error('권한 요청 실패:', error); } }, [service]); return { notifications, token, permission, requestPermission }; }

컴포넌트 구현

2단계 App.jsx

// App.jsx import { useNotification } from './hooks/useNotification'; import './App.css'; function App() { const { notifications, token, permission, requestPermission } = useNotification(); return ( <div className="app"> <h1>웹 푸시 알림 데모</h1> {/* 권한 요청 버튼 */} {permission !== 'granted' && ( <button onClick={requestPermission} className="btn-primary"> 알림 권한 요청 </button> )} {/* FCM 토큰 표시 */} {token && ( <div className="token-display"> <strong>FCM Token:</strong> <code>{token}</code> </div> )} {/* 알림 목록 */} <div className="notifications"> <h2>받은 알림</h2> {notifications.length === 0 ? ( <p className="empty">받은 알림이 없습니다.</p> ) : ( notifications.map(notif => ( <div key={notif.id} className="notification-item"> <h3>{notif.title}</h3> <p>{notif.body}</p> <small>{notif.timestamp.toLocaleString()}</small> </div> )) )} </div> </div> ); } export default App;

3단계 App.css

.notification-item { background: #f7fafc; border-left: 4px solid #61dafb; padding: 15px; margin: 10px 0; border-radius: 8px; } .token-display { background: #ebf8ff; padding: 15px; border-radius: 8px; margin: 20px 0; } .btn-primary { background: #61dafb; color: #282c34; padding: 12px 24px; border: none; border-radius: 6px; cursor: pointer; font-size: 16px; font-weight: 600; } .btn-primary:hover { background: #21a1c4; }

환경 변수 설정

.env 파일 생성:

REACT_APP_FIREBASE_API_KEY=your_api_key REACT_APP_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com REACT_APP_FIREBASE_PROJECT_ID=your_project_id REACT_APP_FIREBASE_STORAGE_BUCKET=your_project.appspot.com REACT_APP_FIREBASE_MESSAGING_SENDER_ID=your_sender_id REACT_APP_FIREBASE_APP_ID=your_app_id REACT_APP_FIREBASE_VAPID_KEY=your_vapid_key

실행 방법

  1. Firebase 프로젝트 생성 및 VAPID 키 발급
  2. .env 파일에 Firebase 설정 입력
  3. public/firebase-messaging-sw.js 생성
  4. npm install - 패키지 설치
  5. npm start - 개발 서버 실행
  6. "알림 권한 요청" 버튼 클릭

다른 프레임워크 예제도 확인하세요