
🛎️ 팀과 함께 리텐션을 고민하다
그리고 내가 푸시 메시지를 개발하게 된 이야기
최근 마케팅 팀에서 “멤버십 유저 이탈률을 줄이기 위해 리텐션을 높일 방법이 필요하다”는 의견이 팀장님께 전달되었습니다.
그 논의 끝에 ‘놓치기 쉬운 쿠폰과 프로모션을 사용자에게 효과적으로 알리자’는 방향이 정해졌고,
자연스럽게 푸시 메시지 시스템 구축이 필요하다는 결론에 도달했습니다.
그렇게 팀장님은 저에게 푸시 메시지 시스템 개발을 제안하셨고,
“한 번 제대로 만들어보자!”는 마음으로 본격적인 개발을 시작하게 되었죠.
🧩 배경: 리텐션이 중요한 이유
저희 푸짐 서비스에서는 회원 가입 시 한 달 무료 멤버십을 제공해 초기 유입을 유도하고 있습니다.
멤버십 유저는 식자재를 일반가보다 저렴한 가격에 구매할 수 있어 구매 전환율이 높은 편입니다.
하지만 유입되는 멤버십 유저 수와 이탈 유저 수가 거의 비슷하거나, 이탈이 더 많은 경우도 생기고 있었습니다.
따라서 매출을 안정적으로 늘리기 위해서는 기존 사용자의 리텐션을 높이는 것이 핵심 과제로 떠올랐습니다.
🔔 푸시 메시지로 놓치지 않게 알리자
사용자들이 쿠폰이나 프로모션을 몰라서 혜택을 놓치는 일이 종종 있었고,
이런 기회를 제때, 효과적으로 알릴 수 있다면 리텐션 개선에 도움이 될 것이라 판단했습니다.
그래서 사용자 맞춤형 푸시 알림 시스템을 직접 구축하게 되었고,
Flutter WebView 기반 앱에서 FCM(Firebase Cloud Messaging) 연동이라는 다소 생소한 작업에 도전하게 되었습니다.
이 글이 제일 잘 정리되어 있습니다.
Future<void> _sendFcmTokenToWebView() async {
String? token = await FirebaseMessaging.instance.getToken();
if (token != null) {
String os = Platform.isIOS ? 'ios' : 'aos';
await _controller.runJavaScript('''
window.dispatchEvent(new CustomEvent("fcmTokenReceived", {
detail: {
token: "${token}",
os: "${os}"
}
}));
''');
}
}
..addJavaScriptChannel(
'FcmToken',
onMessageReceived: (JavaScriptMessage message) {
_sendFcmTokenToWebView();
},
)
window.dispatchEvent를 통해 JS 이벤트를 날리면 WebView에서 fcmTokenReceived 이벤트를 받아 처리할 수 있습니다.
import android.webkit.WebView
WebView.setWebContentsDebuggingEnabled(true)
이후 chrome://inspect/#devices에서 디버깅 가능!
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
String? imageUrl = message.notification?.android?.imageUrl;
String? landingUrl = message.data['landing_url'];
String? localImagePath;
if (imageUrl != null && imageUrl.isNotEmpty) {
localImagePath = await _downloadAndSaveImage(imageUrl);
}
await _showNotification(
message.notification?.title,
message.notification?.body,
imageUrl: localImagePath,
landingUrl: landingUrl,
);
});
flutter_local_notifications 패키지로 포어그라운드 알림 구현 가능.
Notification Service Extension 필요
📌 팁: 제목 30자 / 본문 35자 정도면 푸시 메시지가 이쁘게 출력됩니다.