콘텐츠로 이동

디바이스 토큰 등록

OS별 푸시 알림 서비스(FCM/APNs)가 발급한 디바이스 토큰을 Hive Axyl 푸시 서버에 등록합니다.

본 문서에서는 OS별로 디바이스 토큰을 발급받고, 발급받은 토큰을 로그인한 사용자와 연결해 푸시 메시지 발송 대상에 포함하는 과정을 안내합니다.


디바이스 토큰 등록 순서는 아래와 같습니다.

※ 사전 요구 사항: 모듈 설치 및 초기화를 완료하고, 토큰 등록 API를 호출하기 전에 로그인을 완료하세요. 토큰 등록은 로그인된 세션을 사용합니다.

  1. OS별 디바이스 토큰 발급
  2. 디바이스 토큰 등록
  3. 토큰 갱신 대응

Hive Axyl 푸시 모듈은 OS별 외부 푸시 서비스에서 발급한 토큰을 Hive Axyl 푸시 서버에 등록합니다. OS별 토큰 발급, 토큰 저장, 알림 권한 요청은 앱 클라이언트에서 직접 수행합니다.

Note
  • 토큰과 연결되는 사용자 식별자(Player ID)는 로그인 토큰에서 추출되며, 요청에 별도로 담지 않습니다.
  • 등록 요청은 접수(202) 후 서버에서 비동기로 처리됩니다.


1. OS별 디바이스 토큰 발급

토큰 등록 전에 각 OS 환경에 해당하는 메시징 인프라 서비스에서 디바이스 토큰을 발급받습니다.

OS 토큰 발급 방법 등록 시 ProviderType
Android FCM 플러그인으로 디바이스 토큰을 발급받습니다. Fcm
iOS APNs 플러그인으로 디바이스 토큰을 발급받고 푸시 환경을 확인합니다. Apns 또는 ApnsSandbox


호출 시 고려 사항

  • Android는 FCM 토큰을 발급받은 뒤 ProviderType에 Fcm을 지정합니다.
  • iOS는 APNs 토큰 발급 후 푸시 환경 확인 결과에 따라 ProviderType에 Apns 또는 ApnsSandbox를 지정합니다.
  • 앱 시작, 로그인, 토큰 갱신처럼 토큰 상태가 달라질 수 있는 시점에 등록 API를 호출해 서버 정보를 최신 상태로 유지하세요.


2. 디바이스 토큰 등록

Method

public Task UpsertTokenAsync();


발급받은 디바이스 토큰을 Hive Axyl 푸시 서버에 등록하거나 전체 동기화합니다. 같은 토큰으로 등록된 정보가 있으면 요청 값으로 전체를 갱신하고, 없으면 새로 등록합니다.

등록할 때마다 토큰 유효 기간이 1년으로 갱신되므로, 앱 시작이나 로그인처럼 주기적으로 반복되는 시점에 호출해 토큰을 최신 상태로 유지하세요. 같은 요청을 다시 보내도 결과가 같으므로 재시도해도 안전합니다.

토큰 등록 요청은 로그인한 세션의 사용자와 연결됩니다. 사용자 식별자는 요청에 직접 포함하지 않습니다.


호출 파라미터

필드명 타입 필수 여부 설명
request UpsertTokenRequest Required 등록할 토큰 정보를 담는 요청 객체입니다.
context ApiCallContext Optional 호출 단위 설정 객체입니다. 생략하면 기본값이 사용됩니다.

UpsertTokenRequest

필드명 타입 필수 여부 설명
Token string Required FCM/APNs가 발급한 디바이스 토큰 값입니다.
TimezoneId string Required 디바이스의 타임존 이름입니다. IANA 형식으로 전달합니다(예: Asia/Seoul). 유효하지 않은 이름이면 요청 값 검증에 실패합니다.
Country string Required 디바이스의 국가 코드입니다. ISO 3166-1 alpha-2 형식으로 전달합니다. 캠페인 발송 시 국가 필터링에 사용합니다.
Language LanguageCode Required 디바이스 토큰의 언어 코드입니다. 알림 메시지의 언어 현지화에 사용합니다. enum 멤버로 지정합니다(예: LanguageCode.Ko).
ProviderType UpsertTokenRequestProviderType Required 토큰을 발급한 푸시 서비스입니다. Android는 Fcm, iOS 운영 환경은 Apns, iOS 개발 환경은 ApnsSandbox를 사용합니다.
Agreement Agreement Required 알림 수신 동의 설정입니다. 세 항목 값을 모두 채워 전달합니다.
AppVersion string Optional 앱 버전입니다.
SdkVersion string Optional Hive Axyl SDK 버전입니다.
ServerId string Optional 사용자가 접속 중인 앱 서버 ID입니다.
EventType string Optional 토큰 등록을 일으킨 이벤트 유형입니다. 기록용 값이며 최대 32자입니다(예: LOGIN).

Agreement

필드명 타입 필수 여부 설명
Info bool Required 정보성 알림 수신 동의입니다.
Advertise bool Required 광고성 알림 수신 동의입니다.
Night bool Required 야간 광고성 알림 수신 동의입니다. Advertise가 false이면 true로 설정할 수 없습니다.


호출 예시

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

using Hive.Axyl.Core;
using Hive.Axyl.Push;

IPushService push = HiveCore.Resolve<IPushService>();

var request = new UpsertTokenRequest {
    Token        = fcmToken,            // FCM 또는 APNs로 발급받은 디바이스 토큰
    TimezoneId   = "Asia/Seoul",        // 디바이스의 IANA 타임존
    Country      = "KR",                // ISO 3166-1 alpha-2
    Language     = LanguageCode.Ko,
    ProviderType = UpsertTokenRequestProviderType.Fcm,
    AppVersion   = "{appVersion}",
    SdkVersion   = "{sdkVersion}",
    ServerId     = "KR-01",             // 사용자가 접속 중인 앱 서버 ID
    Agreement    = new Agreement {      // 수신 동의 - 세 항목을 모두 전달합니다.
        Info      = true,
        Advertise = false,
        Night     = false,
    },
    EventType    = "LOGIN",             // 등록을 일으킨 이벤트(기록용)
};

PushUpsertTokenResult result = await push.UpsertTokenAsync(request);

switch (result)
{
    case PushUpsertTokenResult.Success:
        // 등록 요청 접수 완료(202). 서버가 비동기로 처리합니다.
        break;

    case PushUpsertTokenResult.ResourceNotInScope:
        // 요청한 App ID 또는 리소스를 현재 프로젝트 범위에서 사용할 수 없습니다.
        break;

    case PushUpsertTokenResult.InvalidSubject:
        // 로그인 세션의 사용자 식별자를 사용할 수 없습니다. 로그인 상태를 확인합니다.
        break;

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

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


호출 시 고려 사항

  • Token, ProviderType, Agreement 등 필수 필드를 모두 채워 전달하세요.
  • TimezoneId는 IANA 타임존 이름이어야 합니다. 유효하지 않은 값이면 Failure의 HiveError.ExternalCode에 invalid_parameter가 전달될 수 있습니다.
  • 등록 요청은 서버에서 비동기로 처리됩니다. Success는 요청 접수를 의미합니다.
  • 로그아웃이나 계정 전환으로 더 이상 해당 사용자 대상 알림을 받지 않아야 한다면 토큰 식별자 바인딩 해제를 호출하세요.


응답 상태

반환 객체 PushUpsertTokenResult는 아래 케이스로 분기됩니다. 성공 시 별도의 응답 데이터는 없습니다.

응답 케이스 설명 앱 클라이언트 대응
Success 등록 요청이 접수되었습니다(202). 서버가 비동기로 처리하며, 토큰 유효 기간이 1년으로 갱신됩니다. 등록 완료로 처리
ResourceNotInScope 요청한 App ID 또는 리소스를 현재 프로젝트 범위에서 사용할 수 없습니다. 프로젝트와 App ID 설정 확인
InvalidSubject 로그인 세션에서 토큰에 연결할 사용자 식별자를 확인할 수 없습니다. 로그인 상태 확인 후 재시도
Failure 네트워크, 서버 오류 또는 공통 실패 응답입니다. 요청 값 검증 오류는 Problem(HiveError)의 ExternalCode에 invalid_parameter, missing_field, bad_request 등으로 전달됩니다. ExternalCode 확인 후 요청 값 수정 또는 재시도


3. 토큰 갱신 대응

OS 푸시 서비스가 토큰을 새로 발급하면 앱 클라이언트가 새 토큰을 다시 등록해야 합니다. Hive Axyl SDK는 갱신된 토큰을 자동으로 Hive Axyl 서버에 등록하지 않습니다.

fcm.TokenRefreshed += async newToken =>
{
    var result = await push.UpsertTokenAsync(new UpsertTokenRequest {
        Token        = newToken,
        ProviderType = UpsertTokenRequestProviderType.Fcm,
        // 나머지 필드는 최초 등록과 같은 값으로 채웁니다.
    });
    // 응답 상태 분기는 [디바이스 토큰 등록] 단계와 동일합니다.
};

Android의 TokenRefreshed 이벤트는 FCM 토큰 발급을 참고하세요. iOS의 TokenRefreshed 이벤트는 APNs 토큰 발급을 참고하세요.


참고: 발급부터 등록까지의 구현 예시

OS별 전용 플러그인을 통한 디바이스 토큰 발급(FCM/APNs) 과정과, Hive Axyl 코어 모듈을 통한 푸시 서버 등록 단계를 하나로 연결한 전체 구현 예시를 안내합니다.

아래 구현 예시 코드는 성공 케이스(조기 반환을 통한 예외 처리 생략) 중심으로 구성됩니다. 각 메서드 호출 단계별 구체적인 실패 유형 및 오류 처리는 해당 단계의 개별 문서에 안내된 switch 예시를 참조하세요.

using Hive.Axyl.Core;
using Hive.Axyl.Push;
#if UNITY_ANDROID
using Hive.Axyl.Push.Addon.FCM;
#elif UNITY_IOS
using Hive.Axyl.Push.Addon.APNS;
#endif

async Task RegisterDeviceTokenAsync()
{
    string token;
    UpsertTokenRequestProviderType providerType;

#if UNITY_ANDROID
    IFCMPlugin fcm = HiveCore.Resolve<IFCMPlugin>();
    if (await fcm.GetTokenAsync() is not FcmServiceGetTokenResult.Success fcmToken)
    {
        return; // 실패 분기는 [FCM 토큰 발급]의 응답 상태를 참고해 처리합니다.
    }
    token        = fcmToken.Data.Token;
    providerType = UpsertTokenRequestProviderType.Fcm;
#elif UNITY_IOS
    IAPNSPlugin apns = HiveCore.Resolve<IAPNSPlugin>();
    if (await apns.GetTokenAsync() is not ApnsServiceGetTokenResult.Success apnsToken)
    {
        return;
    }
    if (await apns.GetProviderEnvironmentAsync()
            is not ApnsServiceGetProviderEnvironmentResult.Success env)
    {
        return;
    }
    token        = apnsToken.Data.Token;
    providerType = env.Data.Environment == ProviderEnvironment.Apns
        ? UpsertTokenRequestProviderType.Apns
        : UpsertTokenRequestProviderType.ApnsSandbox;
#else
    return; // 지원하지 않는 OS입니다.
#endif

    IPushService push = HiveCore.Resolve<IPushService>();

    var result = await push.UpsertTokenAsync(new UpsertTokenRequest {
        Token        = token,
        ProviderType = providerType,
        // TimezoneId, Country, Language, Agreement 등 나머지 필드는
        // [디바이스 토큰 등록]의 호출 파라미터 표를 참고해 채웁니다.
    });
    // 응답 상태 분기는 [디바이스 토큰 등록] 단계와 동일합니다.
}


참고: 토큰과 사용자 연결

토큰을 등록하면 로그인한 사용자(Player ID)와 토큰이 연결됩니다. 로그아웃이나 계정 전환으로 더 이상 해당 사용자 대상 알림을 받지 않아야 한다면 토큰 식별자 바인딩 해제를 호출하세요.


연관 문서

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