푸시 알림
푸시 알림을 전송하고 처리합니다.
개요
Firebase Cloud Messaging(FCM)을 통한 푸시 알림을 지원합니다.
| 기능 | Android | iOS |
|---|---|---|
| FCM 토큰 조회 | ✓ | ✓ |
| 포그라운드 수신 | ✓ | ✓ |
| 알림 클릭 처리 | ✓ | ✓ |
지원 플랜: Basic 이상
사전 준비
Android
Firebase 프로젝트 설정이 필요합니다. 개발 환경 설정 문서를 참고하여 google-services.json을 앱에 추가하세요.
알림 표시 권한 POST_NOTIFICATIONS는 AndroidManifest.xml에 기본 활성화되어 배포됩니다 (Android 13+에서 런타임 권한 요청 필요). 별도 주석 해제가 필요 없습니다.
iOS
APNs(Apple Push Notification service) 설정이 추가로 필요합니다.
- Apple Developer → Certificates, Identifiers & Profiles → Keys → APNs 키 생성 (또는 APNs 인증서 발급)
- Xcode → 프로젝트 타겟 선택 → Signing & Capabilities →
+ Capability→ Push Notifications 추가 - Firebase 콘솔 → 프로젝트 설정 → Cloud Messaging → APNs 키(또는 인증서) 업로드
GoogleService-Info.plist를 Xcode 프로젝트에 추가하면 APNs와 FCM이 자동으로 연동됩니다.
포그라운드 알림 동작 차이 (iOS)
iOS는 기본적으로 앱이 포그라운드 상태일 때 알림 배너를 표시하지 않습니다. SDK가 이를 처리하여 전역 함수 window.onFCMReceived(...)를 호출하므로, 인앱 알림 UI를 직접 구현하면 됩니다.
FCM 토큰 조회
앱 실행 후 FCM 토큰을 가져와 서버에 저장합니다. 이 토큰을 사용하여 특정 기기로 푸시를 발송합니다.
unveilyBridge.fetchFCMToken(cb)는 코어 메서드로, cb는 결과를 받을 콜백 함수 이름 문자열입니다. 생략 시 기본값 'onFCMTokenResult'가 사용됩니다. 콜백은 위치 인자 (token, isSuccess) 형태로 호출됩니다.
window.unveilyBridge.fetchFCMToken("onFCMTokenResult");
function onFCMTokenResult(token, isSuccess) {
if (isSuccess && token) {
savePushToken(token);
}
}
async function savePushToken(token) {
await fetch('/api/push-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token })
});
}서버측 토큰 저장
// Express.js
app.post('/api/push-token', async (req, res) => {
const { token } = req.body;
const userId = req.session.userId;
await db.query(
'INSERT INTO push_tokens (user_id, token) VALUES (?, ?) ON DUPLICATE KEY UPDATE token = ?',
[userId, token, token]
);
res.json({ ok: true });
});// ASP.NET Core
[HttpPost("push-token")]
public async Task<IActionResult> SavePushToken([FromBody] PushTokenRequest request)
{
var userId = User.GetUserId();
await _db.PushTokens.Upsert(new PushToken {
UserId = userId,
Token = request.Token
});
return Ok(new { ok = true });
}// Spring Boot
@PostMapping("/api/push-token")
public ResponseEntity<?> savePushToken(@RequestBody PushTokenRequest request,
@AuthenticationPrincipal UserDetails user) {
pushTokenService.upsert(user.getUsername(), request.getToken());
return ResponseEntity.ok(Map.of("ok", true));
}<?php
$data = json_decode(file_get_contents('php://input'), true);
$token = $data['token'];
$userId = $_SESSION['user_id'];
$stmt = $pdo->prepare(
'INSERT INTO push_tokens (user_id, token) VALUES (?, ?)
ON DUPLICATE KEY UPDATE token = ?'
);
$stmt->execute([$userId, $token, $token]);
header('Content-Type: application/json');
echo json_encode(['ok' => true]);<%
Dim token, userId
token = Request.Form("token")
userId = Session("user_id")
Dim conn, sql
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open Application("ConnectionString")
sql = "IF EXISTS (SELECT 1 FROM push_tokens WHERE user_id = " & userId & ") " &
"UPDATE push_tokens SET token = '" & token & "' WHERE user_id = " & userId &
" ELSE INSERT INTO push_tokens (user_id, token) VALUES (" & userId & ", '" & token & "')"
conn.Execute sql
Response.ContentType = "application/json"
Response.Write "{""ok"": true}"
%>푸시 수신 및 클릭 처리
메시지를 수신하거나 사용자가 알림을 탭하면, SDK가 웹 앱이 정의한 전역 함수 window.onFCMReceived(title, body, dataJson)를 호출합니다. 세 번째 인자 dataJson은 커스텀 데이터 페이로드를 담은 JSON 문자열입니다.
window.onFCMReceived = function (title, body, dataJson) {
const data = dataJson ? JSON.parse(dataJson) : {};
// 딥링크(예: 알림 클릭 시 이동할 URL)
if (data.url) {
window.location.href = data.url;
return;
}
// 포그라운드 수신 — 인앱 알림 UI 표시
showInAppNotification({ title, body });
};포그라운드 수신과 알림 클릭은 모두 window.onFCMReceived(또는 딥링크)로 전달됩니다. 별도의 'unveily-event' CustomEvent나 addEventListener는 사용하지 않습니다. 클릭 시 이동은 데이터 페이로드의 url 같은 필드로 직접 분기하세요.
커스텀 데이터 페이로드 예시
발송 시 data에 담은 값이 dataJson 문자열로 전달됩니다.
{
"title": "새 주문이 도착했습니다",
"body": "주문 #1234를 확인하세요",
"data": {
"url": "/orders/1234",
"orderId": "1234"
}
}