-
Notifications
You must be signed in to change notification settings - Fork 0
Frontend Push Guide
상태: 토큰 등록/해제(A)는 머지됨(PR #153 / 이슈 #152). 발송·payload(B)는 리뷰 중(PR #156 / 이슈 #155). 대응: FE 요청 문서
BE-Request-App의 A·B 항목 —pushNotifications.ts·appShell.ts
- Base URL:
https://api.ditto.pics - 인증 헤더 (모든
/api/**):X-API-Key: <키>+Authorization: Bearer <accessToken> - 응답 래핑: HTTP는 항상 200. 성공/실패는
success로 구분합니다.{ "success": true, "data": { }, "error": null } { "success": false, "data": null, "error": { "statusCode": 404, "code": "8301", "message": "등록되지 않은 디바이스입니다." } }
서버는 FCM Admin SDK 한 경로로 iOS/Android 모두 발송합니다. iOS에서 APNs 디바이스 토큰(64자 hex)을 등록하면 등록은 성공하지만 발송이 전부 실패합니다(서버는 토큰을 해석하지 않고 저장만 합니다). @capacitor/push-notifications는 iOS에서 기본적으로 APNs 토큰을 주므로, 합의대로 @capacitor-firebase/messaging 전환이 선행돼야 합니다. FCM 등록 토큰은 콜론이 섞인 150~170자 문자열입니다.
POST /api/v1/notifications/devices
Content-Type: application/json
{ "token": "dGVzdC1pbnN0YW5zZQ:APA91b...", "platform": "IOS" }
| 필드 | 필수 | 설명 |
|---|---|---|
token |
O | FCM 등록 토큰 그대로 (최대 512자) |
platform |
O |
IOS / ANDROID (대문자) |
{ "success": true, "data": { "registered": true }, "error": null }-
로그인 직후·앱 실행·토큰 갱신(
tokenReceived) 때마다 호출하세요. 재호출해도 행이 늘지 않습니다(멱등). -
registered는 "이번 호출로 이 회원 소유가 됐는지"입니다. 신규 등록·소유권 이전이면true, 이미 내 토큰이던 재호출이면false—false도 실패가 아닙니다. 실패는success가 말합니다. - 다른 회원의 토큰이었다면 소유자를 요청 회원으로 갱신합니다(공용 기기에서 계정이 바뀐 경우 — 이전 회원의 알림이 남의 폰에 뜨지 않게).
- 한 회원이 기기 여러 개(폰·태블릿)를 등록할 수 있습니다.
DELETE /api/v1/notifications/devices/{token}
{ "success": true, "data": null, "error": null }- 로그아웃·탈퇴 직전에 호출하세요. 탈퇴 후에는 인증이 막혀 호출할 수 없습니다.
- 토큰은 경로 변수이므로
encodeURIComponent처리하세요. - 이미 없는 토큰이어도 성공합니다(멱등). 다른 회원의 토큰이면
8301(404)입니다 — 계정 전환 후 이전 계정의 로그아웃 처리에서 이 응답이 올 수 있으니 실패로 노출하지 말고 무시하세요.
서버는 인앱 알림(Frontend-Notification-Guide)이 쌓이는 그 시점에 푸시를 함께 보냅니다. 행이 생긴 알림만 푸시가 나가므로 중복 정책(같은 사건 1회, 새 메시지 접기)이 푸시에도 그대로 적용됩니다.
{
"notification": { "title": "새 메시지", "body": "산책러버: 주말에 시간 되세요?" },
"data": {
"notificationId": "8821",
"type": "CHAT_MESSAGE",
"deepLink": "/chat/one-on-one/305/"
}
}
data 키 |
설명 |
|---|---|
notificationId |
알림 센터의 행 id. 탭 처리 시 PUT /api/v1/notifications/{id}/read로 읽음 처리하세요
|
type |
알림 유형 — 인앱 센터와 같은 enum. 모르는 값은 이동 없이 앱만 여세요(enum은 늘어납니다) |
deepLink |
이동할 경로. 키가 없을 수 있습니다(이동 없음 — 앱만 열기) |
-
data값은 전부 문자열입니다(FCM 규격).notificationId도 문자열로 옵니다. -
notification.title·body는 인앱 센터와 같은 문구입니다. 그대로 표시하세요. -
iOS
badge: 인앱 벨 배지(unread-count)와 같은 기준(최근 30일 미읽음)으로 실려 옵니다.
- 항상
/로 시작하는 앱 내부 경로이며 끝 슬래시가 붙어 있습니다(trailingSlash: true대응). - 유형별 목적지는 Frontend-DeepLink-Guide의 전체 표를 보세요. 알림 센터 목록 응답의
deepLink도 같은 값입니다. - 방이 발송 직전에 사라진 경우 등에는
deepLink키 자체가 빠집니다 — 앱만 여세요.
-
알림 토글(Frontend-MyPage-Settings-Guide)을 끈 카테고리 — 매칭 토글→
MATCHING, 채팅 토글→CHAT. 인앱 센터에는 그대로 쌓입니다(토글은 푸시만 막습니다). - 등록된 기기가 없는 회원(웹 전용).
- 시효가 지난 알림 —
CHAT_MESSAGE는 1시간,CHAT_ENDING_SOON은 6시간이 지나면 FCM이 버립니다(꺼져 있던 기기에 지난 채팅 알림이 몰리지 않게). 나머지 유형은 4주.
| 항목 | 처리 |
|---|---|
| 등록 호출 시점 | 로그인 후 + tokenReceived 리스너 (등록 API가 인증을 요구하므로 비로그인 상태에서 부르면 401) |
| 해제 호출 시점 | 로그아웃 직전. 탈퇴는 서버가 탈퇴 시점에 그 회원의 토큰을 모두 지우므로 앱이 부르지 않아도 됩니다(#154) |
| deepLink 호스트 검증 | 상대 경로만 오지만 기존 appShell.ts 검증 유지 |
| 푸시 탭 처리 |
deepLink 이동 + notificationId로 읽음 API 호출 |
| 포그라운드 수신 | OS가 배너를 띄우지 않을 수 있음 — 인앱 배지 재조회로 처리 |
| code | statusCode | 상황 |
|---|---|---|
8301 |
404 | 다른 회원의 토큰 해제 시도 |
0001 |
400 |
token 누락·512자 초과, platform에 없는 값 |
0002 |
401 | 인증 실패 |
0003 |
403 | API Key 누락 등 |
-
SYSTEM_NOTICE발송 — 발송 주체(어드민 공지 화면)가 없습니다. 유형·게이트 규칙만 준비돼 있습니다. - 탈퇴 시 서버측 토큰 정리 — FE가 탈퇴 전 해제를 부르는 것이 1차 방어이고, 서버측 보강은 #154.
-
네이티브 카카오 로그인 토큰 교환(D)— 구현됐습니다: Frontend-Native-Login-Peer-Profile-Guide.
Firebase 프로젝트 ditto-b780e에 앱 등록이 필요합니다 — Android/iOS 앱 추가(번들 ID pics.ditto.app), google-services.json·GoogleService-Info.plist 반영, iOS는 APNs 키(.p8) 업로드, @capacitor-firebase/messaging 전환. 프로젝트 멤버 초대는 백엔드에 요청하세요.
- 전체 스펙(Swagger UI): https://api.ditto.pics/docs — 태그
Notification - 관련 이슈/PR: #152 · PR #153 / #155 · PR #156
- 설계 배경: 레포
docs/domains/notification.md - 인앱 알림 센터: Frontend-Notification-Guide / 알림 토글: Frontend-MyPage-Settings-Guide