푸시 알림 지원
Firebase Cloud Messaging(FCM)을 Singular SDK와 연동하여 푸시 알림과의 유저 상호작용을 추적하고, 리인게이지먼트 캠페인을 측정하며 전환을 정확하게 어트리뷰션하세요.
아래 구현 가이드를 따라 알림 데이터가 정확한 어트리뷰션을 위해 Singular SDK에 올바르게 전달되도록 하세요.
푸시 알림을 추적하는 이유: 푸시 알림은 리인게이지먼트를 유도하지만, 추적을 위해서는 올바른 연동이 필요합니다. Singular는 알림과 상호작용하는 유저를 정확하게 어트리뷰션하여 마케팅 캠페인과 참여 전략을 최적화합니다.
구현 가이드
FCM 알림 처리
FirebaseMessagingService에서
onMessageReceived()
메서드를 오버라이드하여 푸시 메시지가 도착할 때 알림 데이터를 캡처하세요.
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
var title = ""
var body = ""
message.notification?.let {
Log.d("singular-app", it.toString())
title = it.title ?: ""
body = it.body ?: ""
}
val data: Map<String, String> = message.data
if (data.isNotEmpty()) {
Log.d("singular-app", data.toString())
}
// Forward payload data to intent
processNotification(title, body, data)
}
@Override
public void onMessageReceived(@NonNull RemoteMessage message) {
super.onMessageReceived(message);
String title = "";
String body = "";
if (message.getNotification() != null) {
Log.d("singular-app", message.getNotification().toString());
title = message.getNotification().getTitle();
body = message.getNotification().getBody();
}
Map<String, String> data = message.getData();
if (!data.isEmpty()) {
Log.d("singular-app", data.toString());
}
// Forward payload data to intent
processNotification(title, body, data);
}
모범 사례: 알림 콘텐츠(title, body)와 데이터 페이로드(payload)를 모두 캡처하여 어트리뷰션에 필요한 완전한 추적 정보를 확보하세요.
알림 데이터 처리 및 전달
알림 페이로드(payload)를 첨부한 인텐트로 MainActivity를 실행하여 Singular가 추적 데이터를 수신하도록 하세요.
private fun processNotification(title: String, body: String, data: Map<String, String>) {
val intent = Intent(this, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
// Attach notification data to the intent
data.forEach { (key, value) ->
putExtra(key, value)
}
}
val pendingIntent = PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val notificationBuilder = NotificationCompat.Builder(this, "your_channel_id")
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(body)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as? NotificationManager
notificationManager?.notify(0, notificationBuilder.build())
}
private void processNotification(String title, String body, Map<String, String> data) {
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Attach notification data to the intent
for (Map.Entry<String, String> entry : data.entrySet()) {
intent.putExtra(entry.getKey(), entry.getValue());
}
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "your_channel_id")
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(body)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
notificationManager.notify(0, notificationBuilder.build());
}
}
Android 12+ 요구 사항:
Android API 31+의 보안 요구 사항을 준수하려면
PendingIntent.FLAG_IMMUTABLE
을 사용하세요.
푸시 페이로드(payload)용 SDK 구성
SDK 구성에 푸시 알림 페이로드(payload) 셀렉터(selectors)를 추가하여 Singular 링크가 알림 데이터 구조의 어디에 위치하는지 지정하세요.
푸시 어트리뷰션의 작동 방식.
SDK는
onMessageReceived
내부에서 들어오는 푸시 페이로드(payload)를 파싱하지 않습니다. 대신, 알림에서 액티비티가 실행될 때
링크가 추출됩니다. 즉, OS가 알림 데이터를 실행 인텐트로 전달하면, 이를
SingularConfig
를 통해
Singular.init()
에 전달하게 됩니다. 라이프사이클은 다음과 같습니다:
-
알림 도착 →
onMessageReceived가 이를 표시(개발자 코드). - 유저가 알림을 탭 → Android가 알림 데이터가 첨부된 인텐트로 액티비티를 실행.
-
액티비티가
Singular.init(context, config)를 호출하면서withPushNotificationPayload(intent, selectors)를 통해 인텐트를 전달. - SDK가 셀렉터(selectors)를 따라 Singular 링크를 찾아 푸시 어트리뷰션 세션을 기록.
푸시 어트리뷰션은 알림에서 액티비티가 실행된 후
Singular.init()
가 호출되어야 동작합니다.
withPushNotificationPayload
가 구성되어 있지 않으면 알림이 어떤 방식으로 빌드되었든 링크는 추출되지 않습니다.
setFCMDeviceToken
을 통한 앱 삭제 추적은 별개이며, 푸시 어트리뷰션에는 필요하지 않습니다.
val pushSelectors = arrayOf(
arrayOf("sng_link"),
arrayOf("rootObj", "nestedObj", "anotherNested", "singularLink")
)
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
.withPushNotificationPayload(intent, pushSelectors)
Singular.init(applicationContext, config)
String[][] pushSelectors = {
{"sng_link"},
{"rootObj", "nestedObj", "anotherNested", "singularLink"}
};
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET")
.withPushNotificationPayload(getIntent(), pushSelectors);
Singular.init(getApplicationContext(), config);
셀렉터(selectors) 구성:
-
단순 키:
페이로드(payload)의 최상위 키에는
arrayOf("sng_link")를 사용하세요. -
중첩 키:
중첩된 JSON 구조를 탐색하려면
arrayOf("rootObj", "nestedObj", "key")를 사용하세요. - 여러 경로: 여러 셀렉터(selectors) 배열을 정의하여 Singular 링크가 위치할 수 있는 여러 경로를 확인하세요.
검증 가이드
Start Session에서 페이로드(payload) 검증
Start Session API 호출을 검사하여 푸시 알림 링크가 Singular에 올바르게 전달되었는지 확인하세요.
Singular SDK는 유저가 알림을 탭할 때 Start Session 요청에
singular_link
파라미터로 푸시 알림 페이로드(payload)를 포함합니다.
Start Session 요청 사용 예시:
https://sdk-api-v1.singular.net/api/v1/start?
a=<SDK-Key>
&singular_link=https://singularassist2.sng.link/C4nw9/r1m0?_dl=singular://test&_smtype=3
&i=net.singular.singularsampleapp
&s=1740905574084
&sdk=Singular/v12.6.2
대체 검증 방법: Singular SDK Console을 사용하여 푸시 알림 추적을 검증할 수 있습니다. Deeplink URL 필드에서 추적 링크가 올바르게 캡처되었는지 확인하세요.
고급 구성
ESP 도메인 구성
Singular 링크를 이메일 서비스 제공업체(ESP) 또는 기타 서드파티 도메인으로 래핑한 경우 외부 도메인을 구성하세요.
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
.withESPDomains(listOf("sl.esp.link", "custom.domain.com"))
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET")
.withESPDomains(Arrays.asList("sl.esp.link", "custom.domain.com"));
보안 참고 사항:
기본적으로 Singular Manage Links 페이지에 사전 정의된
sng.link
도메인만 허용됩니다. 래핑된 링크를 사용하는 경우 ESP 도메인을 명시적으로 구성하세요.
동적 딥링크 라우팅
하나의 Singular 추적 링크에 동적 리디렉트 오버라이드를 구성하여 Singular 알림에서 여러 딥링크 목적지를 구현할 수 있습니다.
사용 예시: 여러 액션 옵션이 포함된 속보 알림
-
최신 뉴스 읽기:
newsapp://article?id=12345 -
트렌딩 토픽:
newsapp://trending -
스포츠:
newsapp://sports
여러 개의 추적 링크를 만드는 대신 하나의 Singular 링크를 사용하고 유저의 선택에 따라 동적으로 리디렉트를 오버라이드하세요. 구현 세부 정보는 Singular 추적 링크에서 리디렉트 오버라이드 를 참조하세요.
중요 고려 사항
구현 참고 사항
-
콜백 핸들러 없음:
withSingularLink와 달리, 푸시 알림 기능은 페이로드(payload) 콜백을 제공하지 않습니다. 유저를 앱 내 특정 콘텐츠로 라우팅하려면 자체 딥링크 로직을 구현하세요. -
어트리뷰션 흐름:
유저가 알림을 탭하면 Singular가 페이로드(payload)를 가져와
Singular.init()에 의해 트리거되는 Start Session 이벤트에 포함시킵니다. 백엔드는 이 데이터를 처리하여 푸시 알림 터치포인트를 어트리뷰션하고 리인게이지먼트 추적을 등록합니다. -
도메인 제한:
기본적으로 Manage Links 페이지에 등록된 Singular 링크 도메인(
sng.link)만 허용됩니다. 래핑된 링크를 사용하려면withESPDomains()로 ESP 도메인을 명시적으로 구성하세요.
성공: 이 단계를 따르면 앱이 Singular와 함께 푸시 알림 상호작용을 추적하게 되어 캠페인 성과 인사이트가 향상되고 정확한 리인게이지먼트 어트리뷰션이 가능해집니다.