콘텐츠로 이동

5단계. 리모트 푸시 수신

Android 환경에서 도착한 리모트 푸시 메시지를 앱 클라이언트에서 처리합니다.

본 문서에서는 Hive Axyl FCM 플러그인으로 실행 중 메시지를 수신하고, 사용자가 알림을 탭해 앱이 실행된 경우의 페이로드를 확인하는 과정을 안내합니다.


FCM 푸시 수신 처리 구현 방법은 아래와 같습니다.

FCM 플러그인은 수신 이벤트와 콜드 스타트 메시지 조회 기능만 제공합니다. 메시지 표시 방식, 데이터 해석, 화면 이동 처리는 앱 클라이언트에서 직접 수행합니다.

Note
  • FCM 플러그인은 Android 디바이스 전용입니다. Unity Editor를 포함한 다른 환경에서는 포트가 등록되지 않으므로 OS 분기 또는 HiveCore.TryResolve<T>()로 보호하세요.
  • 백그라운드에서 도착해 시스템 알림으로 표시되는 메시지는 OS가 직접 처리하므로 앱 코드가 개입하지 않습니다.


방법 1. 실행 중 메시지 수신

앱이 메시지를 받을 수 있는 상태에서 원격 메시지가 도착하면 NotificationReceived 이벤트가 발생합니다. 이벤트는 엔진 메인 스레드로 전달되므로 핸들러에서 바로 UI를 다룰 수 있습니다.

FCM SDK 동작에 따라 이벤트 발생 조건은 아래와 같습니다.

  • 포그라운드: 모든 메시지에서 발생합니다.
  • 백그라운드: 데이터(data) 메시지에서만 발생합니다. 알림(notification) 메시지는 시스템 알림으로 표시되며 이벤트가 발생하지 않습니다.


호출 예시

using Hive.Axyl.Core;
using Hive.Axyl.Push.Addon.FCM;

IFCMPlugin fcm = HiveCore.Resolve<IFCMPlugin>();

fcm.NotificationReceived += message =>
{
    // 포그라운드 수신 - 인앱 배너 표시 등 앱이 결정합니다.
    // 데이터 전용 메시지는 message.Notification이 null입니다.
    string title = message.Notification?.Title ?? string.Empty;
    string body  = message.Notification?.Body ?? string.Empty;

    if (message.Data.TryGetValue("deepLink", out var deepLink))
    {
        // 앱이 정의한 데이터 키를 해석해 처리합니다.
    }
};


호출 시 고려 사항

  • NotificationReceived 이벤트를 받으려면 FCM 플러그인 인스턴스가 유지되어야 합니다.
  • 포그라운드에서 알림을 어떻게 표시할지는 앱 클라이언트가 결정합니다.
  • 백그라운드 알림(notification) 메시지는 OS가 시스템 알림으로 표시합니다. 사용자가 알림을 탭해 앱이 실행된 경우에는 알림 탭 진입 처리를 사용하세요.


방법 2. 알림 탭 진입 처리

사용자가 알림을 탭해 앱을 실행하거나 다시 띄운 경우, GetColdStartMessageAsync()로 해당 알림의 데이터 페이로드를 조회합니다.

Method

public Task GetColdStartMessageAsync();


콜드 스타트 메시지 버퍼는 1회용입니다. 일반 실행이거나 이미 한 번 꺼낸 뒤에는 Message가 null인 Success가 반환되며, 이는 실패가 아닙니다. 앱 시작 시점에 한 번 호출해 알림 탭 진입 여부를 확인하세요.

Note

앱이 종료된 상태에서 알림 탭으로 실행된 경우(콜드 런치)는 추가 설정 없이 동작합니다. 앱이 실행 중일 때 알림 탭으로 재진입한 경우(웜 탭)까지 페이로드를 받으려면 호스트 Activity가 onNewIntent를 Hive Axyl로 전달해야 합니다.


호출 파라미터

필드명 타입 필수 여부 설명
ct CancellationToken Optional 호출을 취소할 때 사용하는 취소 토큰입니다. 생략하면 기본값이 사용됩니다.


호출 예시

GetColdStartMessageAsync()의 반환 객체 FcmServiceGetColdStartMessageResult는 성공, 실패 상태로 나뉩니다. 메서드 호출 시 예외(Exception)를 발생시키지 않으며, 모든 처리 결과가 반환 객체로 전달됩니다. 따라서 별도의 try/catch 구문을 사용하지 않고 switch 구문으로 응답 상태를 분기해 처리합니다.

using Hive.Axyl.Core;
using Hive.Axyl.Push.Addon.FCM;

FcmServiceGetColdStartMessageResult result = await fcm.GetColdStartMessageAsync();

switch (result)
{
    case FcmServiceGetColdStartMessageResult.Success success when success.Data.Message != null:
        // 알림 탭으로 진입 - 페이로드를 해석해 특정 화면으로 이동하는 등 처리합니다.
        var data = success.Data.Message.Data;
        break;

    case FcmServiceGetColdStartMessageResult.Success:
        // 일반 실행 또는 이미 꺼낸 버퍼 - 처리할 알림이 없습니다.
        break;

    // 공통 실패 처리 - 자세한 에러 모델은 [에러 처리](PLACEHOLDER_에러처리_링크) 참고
    case FcmServiceGetColdStartMessageResult.Failure failure:
        HiveError err = failure.Problem;
        Debug.LogError($"[{err.Code}] {err.Message} (trace: {err.TraceId})");
        break;

    // 안전망: 알 수 없는 신규 결과
    default:
        Debug.LogWarning($"처리되지 않은 결과: {result.GetType().Name}");
        break;
}


호출 시 고려 사항

  • 앱 시작 시점에 한 번 호출해 알림 탭 진입 여부를 확인하세요.
  • Success가 반환되어도 Message가 null이면 일반 실행이거나 이미 꺼낸 버퍼입니다.
  • 페이로드를 기반으로 화면 이동을 수행할 때는 앱 초기화와 로그인 상태 확인이 끝난 뒤 처리하세요.


응답 데이터

성공 시 FcmServiceGetColdStartMessageResult.Success의 Data에 메시지가 담깁니다.

필드명 타입 필수 여부 설명
Data.Message FcmRemoteMessage Optional 사용자가 탭한 알림의 페이로드입니다. 일반 실행이거나 이미 꺼낸 버퍼면 null입니다.


응답 상태

반환 객체 FcmServiceGetColdStartMessageResult는 아래 케이스로 분기됩니다. switch 구문으로 처리하세요.

응답 케이스 설명 앱 클라이언트 대응
Success 조회에 성공했습니다. 알림 탭 진입이면 Message에 페이로드가 담기고, 일반 실행이면 null입니다. Message 유무로 분기 처리
Failure 네이티브 연동 오류. Problem(HiveError)에 상세가 담깁니다. 일반 실행으로 간주 또는 오류 기록


참고. 수신 메시지 데이터 확인

FCM 메시지는 두 부분으로 구성될 수 있습니다.

  • 알림(notification): 제목, 본문 등 OS가 표시하는 내용입니다. FcmRemoteMessage.Notification으로 전달됩니다.
  • 데이터(data): 앱이 해석하는 키-값 페이로드입니다. FcmRemoteMessage.Data 딕셔너리로 전달됩니다.

앱은 수신한 Data의 키를 해석해 화면 이동, 상태 갱신 같은 동작을 구현합니다. 데이터는 표시되는 알림(notification)에 동봉해 전달하며, 데이터만 단독으로 담은 메시지(무음 푸시, data-only)의 발송 가능 여부는 푸시 발송(서버) 명세를 따릅니다.


참고: FcmRemoteMessage 구조

수신 메시지는 FCM의 원격 메시지(RemoteMessage)를 그대로 옮긴 구조입니다.

필드명 타입 필수 여부 설명
MessageId string Required 메시지 식별자입니다.
SentTime DateTimeOffset Required 발송 시각(UTC)입니다.
From string Required 발신자입니다.
CollapseKey string Required 메시지 병합 키입니다.
Priority int Required 전달 우선순위입니다. 0은 알 수 없음, 1은 높음, 2는 보통입니다.
Ttl TimeSpan Required 메시지 유효 기간입니다.
Data IReadOnlyDictionary<string,string> Required 데이터 페이로드입니다. 데이터가 없으면 빈 딕셔너리입니다(null 아님).
Notification FcmNotification Optional 알림 표시 정보입니다. 데이터 전용 메시지면 null입니다.

FcmNotification

필드명 타입 필수 여부 설명
Title string Required 알림 제목입니다. 값이 없으면 빈 문자열입니다(null 아님, 이하 string 필드 동일).
Body string Required 알림 본문입니다.
ImageUrl string Required 알림 이미지 URL입니다.
Icon string Required 알림 아이콘입니다.
Sound string Required 알림 사운드입니다.
Tag string Required 알림 태그입니다.
ClickAction string Required 알림 탭 시 실행할 액션입니다.
ChannelId string Required Android 알림 채널 ID입니다.
Color string Required 알림 색상입니다.
Link string Required 알림 링크 URL입니다.
TitleLocKey string Required 제목 현지화 키입니다.
BodyLocKey string Required 본문 현지화 키입니다.
TitleLocArgs IReadOnlyList<string> Required 제목 현지화 인자입니다. 없으면 빈 목록입니다.
BodyLocArgs IReadOnlyList<string> Required 본문 현지화 인자입니다. 없으면 빈 목록입니다.


연관 문서

본 문서의 내용과 관련하여 참조하는 문서는 아래와 같습니다.