푸시 알림을 구현하던 중, 다소 당황스러운 상황을 마주했다. 포그라운드에서는 푸시 알림이 한 번만 잘 도착하는데, 백그라운드에서는 동일한 FCM 메시지가 두 번 수신되는 현상이 발생한 것이다. 처음에는 코드에 문제가 있는 줄 알았지만, 원인을 파고들다 보니 Firebase Cloud Messaging(FCM)의 메시지 타입 처리 방식에서 비롯된 문제라는 것을 알게 되었다.
이번 글에서는 이를 어떻게 해결했는지에 대해 공유하고자 한다.
포그라운드에서 FCM 메세지가 정상적으로 한 번만 수신되지만, 백그라운드에서는 동일한 FCM 메시지가 두 번 수신되는 문제가 발생했다.
백그라운드 상태일 때,notification
필드가 포함된 메시지를 수신하면 시스템이 자동으로 알림을 생성하여 표시한다고 한다. 따라서, onBackgroundMessage()
안에서 self.registration.showNotification()
으로 알림을 또 생성하여,
이미 시스템이 자동 생성한 알림과 중복되어 알림이 두 번 표시되는 현상이 발생했던 것이다. 참고
백그라운드 상태에서 FCM 메시지를 전송할 때, notification
필드 대신 모든 정보를 data
필드에 포함시키도록 수정하여 문제를 해결할 수 있었다. 알림의 생성과 표시를 앱에서 직접 제어할 수 있어 중복 알림을 방지할 수 있었다.
FCM에서 메시지를 보낼 때 두 가지 방식이 있다.
notification
메시지
data
메시지
💡 따라서, 이 문제는 메시지를 전송할 때 notification
필드를 아예 제거하고, 모든 정보를 data
필드에 담도록 아래와 같이 변경함으로써 해결할 수 있었다.
// ❌ 잘못된 방식
const messageWithNotification = {
to: '<device_token>',
notification: {
title: '새 알림',
body: '중복될 수 있는 알림입니다',
},
data: {
customKey: 'customValue',
},
};
// ✅ 권장 방식 (개발자가 직접 알림 처리)
const messageWithData = {
to: '<device_token>',
data: {
title: '새 알림',
body: '안전하게 처리된 알림입니다',
customKey: 'customValue',
},
};
firebase-messaging-sw.js
/** 백그라운드 상태에서 FCM에서 보낸 푸시 알림 메시지를 수신할 때 호출하는 로직 */
messaging.onBackgroundMessage(function (payload) {
const notificationTitle = payload.data.title;
const notificationOptions = {
body: payload.data.body,
icon: '/assets/icons/app/64x64.png',
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
기존 코드에서 notification
필드를 쓰지 않고 data
만 사용하는 것으로 수정했기에, 아래와 같이 onBackgroundMessage
로직도 수정해주었다.
이번 경험을 통해 단순히 기능을 구현하는 것에서 그치지 않고, 알림 시스템이 내부적으로 어떻게 작동하는지 이해하는 것이 얼마나 중요한지 다시금 느꼈다. FCM의 notification과 data의 차이는 사소해 보이지만, 사용자 경험을 크게 좌우할 수 있는 요소라고 생각이 든다.
앞으로도 사용자에게 더 좋은 UX를 제공하기 위해 시스템의 특성과 동작 방식을 꼼꼼히 파악해가며 개발해나가야겠다고 생각한다.