웹 푸시 구현 예제
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>웹 푸시 알림 데모</title>
</head>
<body>
<div id="app">
<h1>웹 푸시 알림 데모</h1>
<!-- 알림 권한 요청 버튼 -->
<button id="requestPermission">알림 권한 요청</button>
<!-- FCM 토큰 표시 -->
<div id="tokenDisplay"></div>
<!-- 알림 목록 -->
<div id="notifications"></div>
</div>
<!-- Firebase SDK -->
<script src="https://www.gstatic.com/firebasejs/10.7.1/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/10.7.1/firebase-messaging-compat.js"></script>
<!-- Nativify Bridge FCM -->
<script src="https://cdn.jsdelivr.net/npm/@nativify/notifications@latest/dist/native-bridge-fcm.js"></script>
<script src="app.js"></script>
</body>
</html>
// app.js
// Firebase 설정
window.firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT.firebaseapp.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT.appspot.com",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID",
vapidKey: "YOUR_VAPID_KEY"
};
class NotificationManager {
constructor() {
this.service = null; // 알림 서비스
this.notifications = []; // 받은 알림 목록
this.token = null; // FCM 토큰
}
// 초기화
async init() {
// 알림 서비스 가져오기
this.service = WebBridgeFCM.getNotificationService();
// 서비스 초기화
await this.service.initialize();
// 메시지 수신 리스너 등록
this.service.onMessageReceived(this.handleMessage.bind(this));
// UI 렌더링
this.render();
}
// 권한 요청 및 토큰 발급
async requestPermission() {
try {
// 알림 권한 요청
const permission = await this.service.requestPermission();
if (permission === 'granted') {
// FCM 토큰 발급
this.token = await this.service.getToken();
console.log('FCM Token:', this.token);
// 서버에 토큰 등록 (개인별 푸시용)
await this.registerToken();
this.showToken();
} else {
console.warn('알림 권한이 거부되었습니다.');
}
} catch (error) {
console.error('권한 요청 실패:', error);
}
}
// 서버에 토큰 등록
async registerToken() {
const appId = 'delivery_app_001'; // Console 앱 ID
const appUserId = 'user123'; // 실제 앱 사용자 ID
try {
await this.service.registerUserToken(
appId,
appUserId,
'https://your-server.com/api/notifications'
);
console.log('토큰 등록 완료');
} catch (error) {
console.error('토큰 등록 실패:', error);
}
}
// 메시지 수신 처리
handleMessage(message) {
console.log('푸시 수신:', message);
// 알림 목록에 추가
this.notifications.unshift({
id: Date.now(),
title: message.notification?.title || '알림',
body: message.notification?.body || '',
timestamp: new Date()
});
// UI 업데이트
this.render();
}
// UI 렌더링
render() {
const container = document.getElementById('notifications');
if (this.notifications.length === 0) {
container.innerHTML = '<p>받은 알림이 없습니다.</p>';
return;
}
container.innerHTML = this.notifications.map(notif => `
<div class="notification-item">
<h3>${notif.title}</h3>
<p>${notif.body}</p>
<small>${notif.timestamp.toLocaleString()}</small>
</div>
`).join('');
}
// 토큰 표시
showToken() {
const display = document.getElementById('tokenDisplay');
display.innerHTML = `
<div class="token-display">
<strong>FCM Token:</strong>
<code>${this.token}</code>
</div>
`;
}
}
// 앱 시작
const manager = new NotificationManager();
// DOM 로드 후 초기화
document.addEventListener('DOMContentLoaded', async () => {
await manager.init();
// 권한 요청 버튼 이벤트
document.getElementById('requestPermission').addEventListener('click', () => {
manager.requestPermission();
});
});
public/firebase-messaging-sw.js 파일 생성:
// firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/10.7.1/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.7.1/firebase-messaging-compat.js');
// Firebase 초기화
firebase.initializeApp({
apiKey: "YOUR_API_KEY",
projectId: "YOUR_PROJECT_ID",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
});
const messaging = firebase.messaging();
// 백그라운드 메시지 처리
messaging.onBackgroundMessage((payload) => {
console.log('백그라운드 메시지:', payload);
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: payload.notification.icon || '/icon.png'
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
.notification-item {
background: #f7fafc;
border-left: 4px solid #4f46e5;
padding: 15px;
margin: 10px 0;
border-radius: 8px;
}
.notification-item h3 {
margin: 0 0 10px 0;
color: #2d3748;
}
.notification-item p {
margin: 0 0 5px 0;
color: #4a5568;
}
.notification-item small {
color: #718096;
font-size: 12px;
}
.token-display {
background: #ebf8ff;
padding: 15px;
border-radius: 8px;
margin: 20px 0;
}
.token-display code {
display: block;
background: #2d3748;
color: #68d391;
padding: 10px;
border-radius: 4px;
margin-top: 10px;
word-break: break-all;
}
firebase-messaging-sw.js 파일을 public/ 폴더에 배치index.html과 app.js에 작성