본문 바로가기
React Native

[React Native] Expo Push Notification - API Server

by dev수니 2024. 9. 20.
반응형

지난 포스팅에서는 Expo Push Notification 설정 방법을 알아보았다.

 

이번엔 Expo Push Notification - API 로 서버에서 알림 보내는 방법에 대해 알아보자.

 

서버를 사용하여 푸시 알림 보내기

푸시 알림 자격 증명을 설정하고 를 가져오는 로직을 추가한 후 Expo Push Token HTTPS POST 요청을 사용하여 Expo API로 보낼 수 있다. 데이터베이스가 있는 서버를 설정하여 이를 수행할 수 있다. (또는 command line tool 로 보내거나 앱에서 바로 보낼 수도 있음).

 

HTTP/2 API

HTTP/2 API에 직접 요청을 보내기 (이 API는 현재 어떠한 인증도 필요하지 않음.)

https://exp.host/--/api/v2/push/send 에 다음 HTTP 헤더를 포함하여 POST 요청을 보낸다.

host: exp.host
accept: application/json
accept-encoding: gzip, deflate
content-type: application/json

 

요청 시 단일 메시지 객체 형태로 전송해야함. 최대 100개의 메시지 객체로 구성된 배열. 단, 모두 동일한 프로젝트에 대한 것이어야 한다. Expo 서버에 요청해야 하는 요청 수를 효율적으로 최소화하기 위해 여러 메시지를 보내려는 경우 배열을 사용해야 한다.

[
  {
    "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
    "sound": "default",
    "body": "Hello world!"
  },
  {
    "to": "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]",
    "badge": 1,
    "body": "You've got mail"
  },
  {
    "to": [
      "ExponentPushToken[zzzzzzzzzzzzzzzzzzzzzz]",
      "ExponentPushToken[aaaaaaaaaaaaaaaaaaaaaa]"
    ],
    "body": "Breaking news!"
  }
]

 

Expo 서버는 gzip으로 압축된 요청을 허용한다. 이렇게 하면 많은 수의 알림을 보내는 데 필요한 업로드 대역폭을 크게 줄일 수 있다. SDK는 자동으로 요청을 gzip으로 압축하고 자동으로 요청을 제한하여 부하를 완화하므로 적극 권장한다.

Push Ticket

위의 요청은 두 개의 필드로 이루어진 JSON 객체로 응답하고, data. errors는 메시지가 전송된 순서와 동일한 푸시 티켓data 배열을 포함한다. (또는 단일 수신자에게 단일 메시지를 보내는 경우 하나의 푸시 티켓 객체). 각 티켓 에는 Expo가 알림을 성공적으로 수신했는지 여부를 나타내는 필드(status)와 성공한 경우 나중에 푸시 영수증을 검색하는 데 사용할 수 있는 필드(id)가 포함된다.

Receipt ID와 함께 상태 ok메시지가 Expo 서버에 수신되었다는 의미이며, 사용자가 수신했다는 의미는 아님 (이를 확인하려면 Push Receipts를 확인해야 함 ).

위의 예를 계속하면 성공적인 응답 본문은 다음과 같음.

{
  "data": [
    { "status": "ok", "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" },
    { "status": "ok", "id": "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY" },
    { "status": "ok", "id": "ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ" },
    { "status": "ok", "id": "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA" }
  ]
}

 

개별 메시지에 오류가 있지만 요청 전체에 오류가 없는 경우, 잘못된 메시지의 해당 푸시 티켓은 상태가 이며 error, 아래와 같이 오류를 설명하는 필드가 표시된다.

{
  "data": [
    {
      "status": "error",
      "message": "\\"ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]\\" is not a registered push notification recipient",
      "details": {
        "error": "DeviceNotRegistered"
      }
    },
    {
      "status": "ok",
      "id": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
    }
  ]
}

 

요청 전체가 실패하면 HTTP 상태 코드는 4xx 또는 5xx가 되고 필드는 errors오류 객체 배열(보통 하나)가 된다. 그렇지 않으면 HTTP 상태 코드는 200이 되고 메시지는 Android 및 iOS 푸시 알림 서비스로 전송된다.

 

Push Receipts

Expo는 알림을 수신한 후 각 알림을 대기열에 넣어 Android 및 iOS 푸시 알림 서비스(각각 FCM 및 APN)에 전달합니다. 대부분의 알림은 일반적으로 몇 초 이내에 전달됩니다. 그러나 때로는 알림을 전달하는 데 더 오래 걸릴 수 있으며, 특히 Android 또는 iOS 푸시 알림 서비스가 알림을 수신하고 전달하는 데 평소보다 시간이 오래 걸리거나 Expo 클라우드 인프라가 고부하 상태인 경우 더욱 그렇다.

 

Expo가 Android 또는 iOS 푸시 알림 서비스에 알림을 전달하면 Expo는 Android 또는 iOS 푸시 알림 서비스가 알림을 성공적으로 수신했는지 여부를 나타내는 Push Receipts 만든다. 잘못된 자격 증명이나 서비스 다운타임으로 인해 알림을 전달하는 데 오류가 발생한 경우 푸시 영수증에는 해당 오류에 대한 자세한 정보가 포함된다.

 

Push Receipts를 가져오려면  https://exp.host/--/api/v2/push/getReceipts 로 POST 요청을 보내야한다.

본문은 ids 티켓 ID 문자열 배열인 필드 이름이 있는 JSON 객체여야 한다.

curl -H "Content-Type: application/json" -X POST "https://exp.host/--/api/v2/push/getReceipts" -d '{
  "ids": [
    "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY",
    "ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ"
  ]
}'

 

 

Push Receipt 의 response body는 두 개의 필드와 data. errors이 있는 JSON 객체이며 data receipt ID를 영수증에 매핑한다. 'status' 값이 'error'일 경우에는 선택적으로 message와 details 필드가 포함된다. 요청된 receipt ID에 대한 Push Receipts가 없으면 매핑에 해당 ID가 포함되지 않는다.

{
  "data": {
    "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX": { "status": "ok" },
    "ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ": { "status": "ok" },
    "YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY": { "status": "error", message: "error!!" }
    // When there is no receipt with a given ID (YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYYY in this
    // example), the ID is omitted from the response.
  }
}

 

 

!!!!! 해결해야 할 오류에 대한 정보가 포함되어 있을 수 있기 때문에 Push Receipt를 확인해야 한다.  예를 들어, 기기가 알림을 받을 수 없는 경우 Apple 설명서에 해당 기기로 알림을 보내는 것을 중단하라는 내용이 있다. Push Receipt 에는 이러한 오류에 대한 정보가 포함된다.

Receipt status: ok 라고 표시되어 있어도 기기가 메시지를 수신했다는 보장은 없음. 푸시 영수증의 "ok"는 Android 또는 iOS 푸시 알림 서비스가 알림을 성공적으로 수신했다는 것을 의미한다. 예를 들어 수신 기기가 꺼져 있는 경우 iOS 또는 Android 푸시 알림 서비스는 메시지를 전달하려고 하지만 기기가 반드시 메시지를 수신하지는 않음.

 

요청 전체가 실패하면 HTTP 상태 코드는 4xx 또는 5xx가 되고 errors field 는 오류 객체 배열(보통 하나)이 된다. 그렇지 않으면 HTTP 상태 코드는 200이 되고 메시지가 사용자 기기로 전송된다.

 

정리

backend 서버에서 push 요청을 보내면 push ticket 이 발행되고 response로 해당 내용을 받는다. 그리고 보내진 요청은 expo server의 대기열에 쌓이고, 순차적으로 각 기기에 발송한다. 발송되면 push receipt이 발행되고, push ticket의 id로 push receipt 를 조회할 수 있다. push ticket 와 receipt 둘다 status 가 ok 로 왔다고해서 기기가 반드시 메세지를 수신하지는 않는 점을 알아두고 예외처리를 잘해야한다.

 

반응형

댓글