FCM 시작하기 [2]

참고!! 이 글의 모든 가이드를 따를 필요는 없습니다. 제가 스터디한 내용을 주먹구구로 작성한 내용입니다.
정확한 가이드는 firebase 공식 문서 페이지를 확인하세요!

2 step > google api 호출 방법 변경점 체크, 인증 토큰 발급 및 호출

목표 : 이전 HTTP에서 HTTP v1로 이전을 하고, 새로운 API를 호출한다.

* Admin FCM API 소개
Firebase Admin SDK를 사용하면 자체 백엔드 서비스를 Firebase 클라우드 메시징(FCM)과 통합할 수 있습니다. 
Admin FCM API는 Firebase 서버 인증을 처리하는 동시에 메시지 보내기와 주제 구독 관리를 지원합니다.

* 메시지 보내기
Firebase Admin SDK를 사용하여 최종 사용자 기기에 Firebase 클라우드 메시징 메시지를 보낼 수 있습니다. 
특히 개별 기기, 이름이 지정된 주제, 하나 이상의 주제와 일치하는 조건문에 메시지를 보낼 수 있습니다. 
Admin Node.js SDK는 기기 그룹에 메시지를 보내는 추가 메소드를 제공합니다.
Admin FCM API를 사용하여 다른 타겟 플랫폼(Android, iOS, 웹)에 맞는 메시지 페이로드를 구성할 수 있습니다. 
메시지 페이로드에 여러 플랫폼의 구성 옵션이 있는 경우 FCM 서비스에서는 메시지를 전달할 때 각 플랫폼에 맞게 메시지를 맞춤설정합니다.

* 주제 구독 관리
Firebase Admin SDK는 FCM 주제에 대한 기기 구독 및 구독 취소를 위한 API를 제공합니다. 
이러한 작업으로 한 번에 최대 1,000대의 기기 등록 토큰을 구독하거나 구독을 취소할 수 있습니다.



HTTP v1 API가 가지고 있는 장점 (이전 API에 비해..)


  1. 액세스 토큰을 통한 보안 향상: HTTP v1 API는 OAuth2 보안 모델에 따라 수명이 짧은 액세스 토큰을 사용합니다. 액세스 토큰이 공개되는 경우에도 만료되기 전에 1시간 정도만 악의적으로 사용될 수 있습니다. 새로고침 토큰이 이전 API에서 사용하는 보안 키만큼 자주 전송되지 않으므로 캡처될 가능성이 매우 낮습니다.

1시간동안 유효한 임시토큰을 발급받아서 호출하니까 보안이 향상되는 것 인정!

  1. 여러 플랫폼에서 보다 효율적인 메시지 맞춤설정: 메시지 본문의 경우 HTTP v1 API에 모든 대상 인스턴스에 전달되는 공용 키는 물론 여러 플랫폼의 메시지를 맞춤설정할 수 있는 플랫폼별 키가 있습니다. 이러한 키를 사용하면 메시지 하나로 여러 클라이언트 플랫폼에 약간 다른 페이로드를 전송하는 ‘재정의’를 만들 수 있습니다.

자세히는 못봤는데, 메시지 형식이 조금 변경된 듯 함. 그리고 android, apns를 굳이 분리해서 쓰지 않아도 되는 듯?

  1. 새 클라이언트 플랫폼 버전을 위한 확장성 강화 및 미래 경쟁력 확보: HTTP v1 API는 iOS, Android, 웹에 제공되는 메시지 옵션을 완전히 지원합니다. 각 플랫폼마다 JSON 페이로드에 자체 정의된 블록이 있으므로 FCM에서 필요에 따라 새 버전과 새 플랫폼으로 API를 확장할 수 있습니다.

api가 버전별로 관리(지금은 v1)가 되고 있으니 앞으로의 새 버전 업데이트 등 확장성?이 기대된다.

일단 본인은 GCM 라이브러리를 모두 FCM으로 이관하여야 하는데… 여기서 한 가지 문제가 생겼다… 바로..!

하지만 기기 그룹 메시징이나 멀티캐스트 메시징을 사용하는 앱은 다음 버전의 API를 기다리는 것이 좋습니다. HTTP v1은 이전 API의 해당 기능을 지원하지 않습니다.

본인이 운영하는 시스템 특성상 멀티캐스트 메시징 방식이 필요한데, 아직 없다니.. 기다리는 거나 다른 대응책을 생각해야 할 것 같다..



이후, 2019년 5월 13일 추가한 내용! 이제는 멀티캐스트 방식으로 사용할 수 있다. 내가 사용했던 코드 샘플 예제를 첨부한다.

public BatchResponse sendMulticast(MulticastMessage message) {
    BatchResponse response = null;
    try {
        response = FirebaseMessaging.getInstance().sendMulticast(message);

    } catch (FirebaseMessagingException e) {
        Logger.log("FirebaseMessagingException! We need to retry.");
        ...
    }

    return response;
}

firebase-admin jar의 버전을 6.8.0으로 높였고, 실제로 메시지 송신 부분을 sendMulticast 메소드를 이용하였다.

위치 : /lib/firebase-admin-6.8.0.jar!/com/google/firebase/messaging/FirebaseMessaging.class

public BatchResponse sendMulticast(@NonNull MulticastMessage message) throws FirebaseMessagingException {
    return this.sendMulticast(message, false);
}




변경점


  1. 서버 엔드포인트 업데이트
    • 경로의 /v1로 버전이 지정된다.
    • 경로에 /projects/myproject-ID/ 형식으로 앱의 Firebase 프로젝트 ID가 포함됩니다. 이 ID는 Firebase 콘솔의 일반 프로젝트 설정 탭에서 확인할 수 있다.
    • send 메소드를 :send로 명시적으로 지정한다.
이전 (deprecated)
POST https://fcm.googleapis.com/fcm/send

이후
POST https://fcm.googleapis.com/v1/projects/birdview-hwahae/messages:send
  1. 전송 요청의 승인 업데이트
    • 서버 키 문자열 —> Valid OAuth 2.0 token 으로 변경
    • 추가로 header에 Content-Length를 추가하지 않으면, 411 (Length Required 라는 에러가 떨어지므로 확인하고 넣어줘야 할 것 같음.)
    • Content-Type: JSON은 application/json, 일반 텍스트는 application/x-www-form-urlencoded;charset=UTF-8입니다. (생략 = 일반 텍스트로 간주)
이전 (deprecated)
Authorization: key=AIzaSyZ-1u…0GBYzPu7Udno5aA (key=서버키) 

이후
Authorization: Bearer ya29.ElqKBGN2Ri_Uz…HnS_uNreA (Bearer <valid OAuth2.0 Access Token> ) 
  1. 액세스 토큰 생성 및 가져오기
    • 서비스 계정 (firebase-adminsdk-3bv3k@birdview-hwahae.iam.gserviceaccount.com)을 이용하여 앱 서버 또는 신뢰할 수 있는 환경에서 Firebase 서버 API를 호출할 수 있다.
    • 서비스 계정을 인증하고 Firebase 서비스에 액세스하도록 승인하려면 JSON 형식의 비공개 키 파일을 생성하고 이 키를 사용하여 수명이 짧은 OAuth 2.0 토큰을 발급받아야 한다.
    • 유효한 토큰을 확보했으면 원격 구성, FCM 등 다양한 Firebase 서비스의 요구사항에 따라 서버 요청에 토큰을 추가할 수 있다.

/**



  1. 전송 요청의 페이로드 업데이트 HTTP v1 API를 사용하면 메시지의 교차 플랫폼 타겟팅이 단순해지는 것 외에도 플랫폼별 메시지를 유연하게 맞춤설정할 수 있다.
- 이전 (deprecated)
// Android
{
  "to": "/topics/news", 
  "notification": { 
    "title": "Breaking News", 
    "body": "Check out the Top Story.", 
    "click_action": "TOP_STORY_ACTIVITY" 
  }, 
  "data": { 
    "story_id": "story_12345" 
  } 
}

// iOS
{
  "to": "/topics/news", 
  "notification": { 
    "title": "Breaking News", 
    "body": "New news story available.", 
    "click_action": "HANDLE_BREAKING_NEWS" 
  }, 
  "data": { 
    "story_id": "story_12345" 
  } 
}


- 이후
{
  "message": { 
    "topic": "news", 
    "notification": { 
      "title": "Breaking News", 
      "body": "New news story available." 
    }, 
    "data": { 
      "story_id": "story_12345" 
    }, 
    "android": { 
      "notification": { 
        "click_action": "TOP_STORY_ACTIVITY", 
        "body": "Check out the Top Story" 
      } 
    }, 
    "apns": { 
      "payload": { 
        "aps": { 
          "category" : "NEW_MESSAGE_CATEGORY" 
        } 
      } 
    } 
  } 
}



결과는 성공!
-> 테스트 코드를 작성하여 안드로이드 폰에 우선적으로 날려보았더니 잘 되는 것 확인!!! :)

[콘솔 결과] Successfully sent message: projects/my-project/messages/0:XXXXXX



참고


FCM HTTP v1 API에 대한 추가 샘플 및 자세한 내용은 Firebase 블로그를 참조하세요.
https://firebase.google.com/docs/cloud-messaging/migrate-v1