'파이어베이스'에 해당되는 글 2건

  1. 2019.02.14 [FCM] #3. Firebase 메시지 전송 (2)
  2. 2019.01.24 [FCM] #1. 소개 및 메시지

[FCM] #1. 소개 및 메시지

[FCM] #2. Firebase 프로젝트 생성 및 Android 앱 FCM 설정

[FCM] #3. Firebase 메시지 전송

[FCM] #4. Android 메시지 처리




일반적인 FCM(Firebase Cloud Message) 발송은 앱 서버에서 FCM 서버로 메시지 요청을 보내고, FCM 서버에서는 다시 클라이언트 기기 앱에 메시지를 보낸다. 


#2에서는 FCM 서버에서 클라이언트 기기로 수신되도록 세팅을 하였다. 

이번 #3에서는 앱 서버에서 FCM 서버로 메시지 요청을 보내는 방법에 대해서 알아본다. 


FCM 서버로 전송하는 방법으로는 크게 3가지 구분된다. 


1. Firebase Admin SDK 이용

2. HTTP V1 API 이용

3. 기존 HTTP API 이용


각 전송 방법 별로 가능한 수신 분류에 대해 정리하였다. 

 

단일 기기

멀티캐스트

(여러 기기)

기기 그룹 

주제 구독 

 Firebase Admin SDK

O

X

X

 HTTP V1 API

O

X

O

 기존 HTTP API

O

O

O

추가로 #2에서 Android Studio에서 기기 그룹이나 주제 구독에 대한 처리를 하지 않았으므로 단일 기기로만 발송테스트를 진행한다. 


Firebase Admin SDK로 발송 

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

위 소개글에 보면 주로 백엔드 관리툴에서 테스트 형태로 사용할 수 있다는 의미인거 같다.  사실 3가지 방법 중 가장 심플한 방법으로 백엔드 관리툴에 붙여도 된다. 

환경설정 및 초기화

Admin SDK를 사용하려면, 아래 3가지 방법 중 하나를 사용해야 한다. 
- projectId Firebase 앱 옵션을 명시적으로 지정합니다.

서비스 계정 사용자 인증 정보로 SDK를 초기화합니다.

- GCLOUD_PROJECT 환경 변수를 설정합니다.

우리는 서비스 계정 사용자 인증 정보로 SDK 초기화 사용한다. 


먼저 사용해야할 비공개 키를 발급받는다.


Firebase 콘솔에서 설정>서비스계정에 들어가면 새 비공개 키 생성 이라는 버튼이 보인다. 


문구에서도 나와 있듯이 공개 저장소에는 넣지 말자.

추가로 json 파일은 내용을 열어서 확인해 보면 좋다. 

프로젝트 관련 비밀키 및 환경 정보들이 들이있다. 


각자 자바 프로젝트 생성하자.

다운로드를 받은 json 파일을 넣자. 

본인은 기본 클래스패스인 resource에 넣었다. 


종속성도 처리하자. 본인은 maven을 사용하므로 pom.xml에 종속성을 추가하였다. 


  com.google.firebase
  firebase-admin
  6.4.0

이제 SDK 초기화 코드를 넣어 보자.

InputStream serviceAccount = null;
FirebaseOptions options = null;
try {
    ClassPathResource resource = new ClassPathResource("fcmmsg.json");
    serviceAccount = resource.getInputStream();
    options = new FirebaseOptions.Builder()
        .setCredentials(GoogleCredentials.fromStream(serviceAccount))
        .build();
    FirebaseApp.initializeApp(options, "fcmmgs");
} catch (FileNotFoundException e) {
    logger.error("Firebase ServiceAccountKey FileNotFoundException" + e.getMessage());
} catch (IOException e) {
    logger.error("FirebaseOptions IOException" + e.getMessage());
}

이것으로 Admin SDK 설정 및 초기화가 완료 되었다. 

추가 정보는 https://firebase.google.com/docs/admin/setup?authuser=0#initialize_the_sdk 여기를 참조하자. 

전송

개별 기기로 전송하는 부분을 추가한다.  
Notification notification = new Notification("타이틀","내용");

Message message = Message.builder()
.putData("score", "850")
.putData("time", "2:45")
.setToken("기기토큰정보")
.setNotification(notification)
.build();

String response = null;
try {
    response = FirebaseMessaging.getInstance(FirebaseApp.getInstance("fcmmsg")).send(message );
} catch (FirebaseMessagingException e) {
    logger.error("Firebase FirebaseMessagingException" + e.getMessage());
    e.printStackTrace();
}

추가 정보는 https://firebase.google.com/docs/cloud-messaging/admin/send-messages?authuser=0 여기를 참조하자.


에뮬레이터로 확인해 보면 메시지가 온 것을 확인할 수 있다. 

HTTP V1 API 발송

기존 HTTP API 보다 액세스 토큰을 통한 보안 향상, 확장성 강화, 메시지 맞춤설정 등 장점이 많다.
HTTP API는 발송하는 서버키 값이 고정인데 반해 HTTP V1은 발송하는 서버키 값을 엑세스 토큰으로 받아서 사용하는 부분이 다르다. 
하지만 멀티캐스트 메시징을 지원하지 않아 아직까지는 기존 HTTP API를 많이 사용한다. 

환경설정 및 초기화

본인은 http 플로그인을 okhttp를 사용하기 위에 종속성을 추가하였다. 


 com.squareup.okhttp3
 okhttp
 3.9.1

HTTP V1 API를 사용하기 위해 초기화 코드를 넣는다. 

GoogleCredential googleCredential = null;
InputStream serviceAccount = null;
String SCOPES = "https://www.googleapis.com/auth/firebase.messaging";
try {
    ClassPathResource resource = new ClassPathResource("fcmmsg.json");
    serviceAccount = resource.getInputStream();
    googleCredential = GoogleCredential
            .fromStream(serviceAccount)
            .createScoped(Arrays.asList(SCOPES));
} catch (IOException e) {
    e.printStackTrace();
}
알림 메시지 구조
아래 정보는 알림메시지 샘플데이터다. 
기존 HTTP 알림메시지와는 조금 다르다. 
{
  "message": {
    "token": "bk3RNwTe3H0:CI2k_...",
    "notification": {
      "title": "Breaking News",
      "body": "New news story available."
    },
    "data": {
      "story_id": "story_12345"
    }
  }
}
//com.google.gson 사용
JsonObject jsonObj = new JsonObject();
jsonObj.addProperty("token", "토큰정보");
JsonObject notification = new JsonObject();
notification.addProperty("body", "\uD83D\uDE03바디V1");
notification.addProperty("title", "\uD83D\uDE03타이틀V1");
jsonObj.add("notification", notification);
JsonObject message = new JsonObject();
message.add("message", jsonObj);

전송

요청할 URL은 아래와 같다. 
https://fcm.googleapis.com/v1/projects/프로젝트ID/messages:send
Firebase 콘솔로 들어가서 프로젝트 ID는 설정>일반 메뉴에서 볼 수 있다. 


전송 코드를 추가한다. 

추가 정보는 https://firebase.google.com/docs/cloud-messaging/migrate-v1?authuser=0 여기를 참조하자.


final MediaType mediaType = MediaType.parse("application/json");
OkHttpClient httpClient = new OkHttpClient();
try {

    Request request = new Request.Builder().url("https://fcm.googleapis.com/v1/projects/fcmmsg/messages:send")
        .addHeader("Content-Type", "application/json; UTF-8")
        .addHeader("Authorization", "Bearer " + googleCredential.getAccessToken())
        .post(RequestBody.create(mediaType, message.toString())).build();
    Response response = httpClient.newCall(request).execute();
    logger.info("Successfully sent message: " + response);
} catch (IOException e) {
    logger.error("Error in sending message to FCM server " + e);
}

에뮬레이터로 확인해 보면 메시지가 온 것을 확인할 수 있다. 

기존 HTTP API 발송

아직 많이 사용하고 있는 방식이다. 

메시지 가공 및 발송


//메시지 가공
JsonObject jsonObj = new JsonObject();
//token
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree("등록토큰");
jsonObj.add("to", jsonElement);
//Notification
JsonObject notification = new JsonObject();
notification.addProperty("title", "\uD83D\uDE03타이틀HTTP");
notification.addProperty("body", "\uD83D\uDE03바디HTTP");
jsonObj.add("notification", notification);

/*발송*/
final MediaType mediaType = MediaType.parse("application/json");
OkHttpClient httpClient = new OkHttpClient();
try {
    Request request = new Request.Builder().url("https://fcm.googleapis.com/fcm/send")
        .addHeader("Content-Type", "application/json; UTF-8")
        .addHeader("Authorization", "key=" + "서버키값")
        .post(RequestBody.create(mediaType, jsonObj.toString())).build();
    Response response = httpClient.newCall(request).execute();
    String res = response.body().string();
    logger.info("notification response " + res);
} catch (IOException e) {
    logger.info("Error in sending message to FCM server " + e);
}
등록토큰은 기기 토큰 값을 넣어준다.

서버키값은 Firebase 콘솔에 가서 설정>클라우드 메시징에 가면 정보가 있다. 

알림메시지 구조

to는 기기 토큰, 기기 그룹 토큰, 주제가 들어갈수 있다. 

멀티 캐스트로 발송하려면 to를 사용하지 않고 registration_ids를 사용한다. 

{
  "to": "",
  "notification": {
    "title": "Breaking News",
    "body": "New news story available."
  },
  "data": {
    "story_id": "story_12345"
  }
}

에뮬레이터로 확인해 보면 메시지가 온 것을 확인할 수 있다. 

마치며

여러기기에 메시지를 전송하는 멀티캐스트는 기존 HTTP API만 가능하다. 
보안이나 확장성이 강화된 HTTP V1 API가 있지만
아직까지는 기기 그룹이나 주제 구독 보다는 멀티캐스트를 많이 사용하므로 기존 HTTP API가 주로 사용된다.  


다음 주제는 안드로이드 메시지 처리에 대해서 알아본다. 


Posted by 사용자 피랑이

댓글을 달아 주세요

  1. 김동용 2019.08.28 16:59  댓글주소  수정/삭제  댓글쓰기

    안녕하세요 작성하신 글 잘 읽어보았습니다.
    작성자님의 글을보고 따라하고있었는데요 서버키 json 파일 다운받은 후부터 설명하신게 이해하기 힘듭니다..(뭔가 중간에 생략되어있는것 같구..ㅠㅠ 그리고 혹시 모든 작업을 안드로이드 스튜디오에서 작업하신건가요?? 만약 그렇다면 maven과 pom.xml은 어떻게 사용하신건지...)
    혹시 실례가 안된다면 조금 더 자세하게 설명해 주실수 있으신가요?

  2. 개혁 2019.09.03 10:47  댓글주소  수정/삭제  댓글쓰기

    글 잘봤습니다. 하지만 내용이 길어지면 해당 내용을 볼수가없습니다.

    어떤 방법이 있을까요?

[FCM] #1. 소개 및 메시지

[FCM] #2. Firebase 프로젝트 생성 및 Android 앱 FCM 설정

[FCM] #3. Firebase 메시지 전송

[FCM] #4. Android 메시지 처리


FCM은 Firebase 클라우스 메시징의 약자이고, 무료로 메시지를 안정적으로 전송할 수 있는 교차 플래폼 메시징 솔루션이다.

IOS, Android, Web등 기존에 메시지를 발송하려면 APNS, GCM 등 각각 환경별로 개발해야하는 불편함이 있었다.  

FCM을 이용하면 이러한 부분을 한번에 처리할 수 있다.  

구글에서는 FCM에 적극적으로 투자하고 있고,  앞으로 새로운 기능들은 모두 FCM을 통해 지원할 예정이다. 

GCM 서비스는 기존 Legacy 앱에 대한 지원 이유로 현재 버전으로만 유지하고 있다. 

주요 기능

메세지 타입, 타겟팅, 클라 앱에서 전송 3가지로 구분된다. 

메세지 타입

알림 메세지와 데이터 메세지로 구분된다. 

 타입

알림 가능 여부

 알림 저장 개수

알림 처리 방법

 알림 메세지

 O

여러 알림을 저장하나 OS 환경마다 다름

앱이 백그라운드 일 때 

 데이터 메세지

 

1개의 알림만 저장

앱이 포그라운드 일 때

보통은 알림 및 데이터 메세지를 같이 혼용하여 사용한다. 

예를 들어 휴대폰 푸시 알림은 알림 메세지,  알림을 클릭하였을 때 앱 내 특정 페이지로 이동이나, 어떠한 액션은 데이터 메세지를 통해서 이뤄진다. 

타겟팅

단일 기기, 기기 그룹, 주제를 구독한 기기 3가지 방식으로 전송 가능하다. 

 전송 방식

대상 수

설명

단일 기기

1개

 하나의 기기 (앱 기준)

기기 그룹

20개

 알림 키에 허용되는 그룹

주제 구독

1000개

 등록 토큰에 구독된 기기

클라이언트 앱에서 메세지 전송

기기에서 Firebase Connections Server로 메시지를 전송한다. 
예를 들어 기기에서 채팅 및 특정 기타 메시지 보낸다. 

작동 원리

크게 송신자, FCM, 수신자로 구분된다. 

송신자는 주로 앱서버나 백오피스 정도의 GUI 콘솔이 되고, 수신자는 우리가 흔히 쓰는 ios나 android 기기이다.

구현 방법

먼저 Firebase를 가입하고 프로젝트 생성 후 FCM을 설정한다. 
클라이언트 앱에서 Firebase 관련 라이브러리를 다운로드 받은 후에 FCM에 해당 클라이언트 앱을 등록한다. 
수신부분까지 세팅이 완료되면 Firebase 관리 콘솔을 이용하여 클라이언트에 메시지가 정상적으로 알림 처리가 되는지 확인한다.
Firebase Connection Server로 발송할 수 있는 서비스형 어플리케이션을 개발한다. 

 방법

설명

FCM SDK 설정

 - OS별로 FCM  설정

클라이언트 앱 개발

 - 클라이언트 앱에 Firebase 메시지를 수신할 수 있도록 처리

 - 메시지 처리 / 주제 구독 로직

앱 서버 개발

 - SDK, http, http v1 중 선정하여 메시지 작성 및 FCM에 발송 처리

 - 업스트림 메시징은 XMPP 프로토콜을 사용해야 함

 - XMPP(Extensible Messaging and Presence Protocol) XML에 기반한 메시지 지향 미들웨어용 통신 프로토콜

메시지 정보

FCM은 공통 메시지 옵션 외에 IOS 및 Android 별로 배지, 사운드, 아이콘 등 다양한 메시지 옵션을 제공한다. 

Firebase 콘솔에서 테스트 형태로 메시지 전송 가능하다.

메시지 유형

알림 메시지와 데이터 메시지로 구분된다. 

 유형

설명

 Key-Value 구조

 예시

(Http V1 Api 기준)

 알림 메시지

 - 알림 표시 메시지

 - FCM SDK에서 자동 처리됨

 - 데이터 메시지 포함 가능

 - 미리 정의됨

 {

  "message":{

    "token":"bk3RNwTe3H0:CI2k_...",

    "notification":{

      "title":"Portugal vs. Denmark",

      "body":"great match!"

    }

  }

}

 데이터 메시지

 - 클라이언트 앱에서 처리

 - 앱 서버와 커스텀 키 설정

 - 정의 해야함

 {

  "message":{        "token":"bk3RNwTe3H0:CI2k_HHwgI...",

    "data":{

      "Nick" : "Mario",

      "body" : "great match!",

      "Room" : "PortugalVSDenmark"

    }

  }

}

앱 상태에 따른 처리

백그라운드 

 알림 메시지가 알림 목록으로 전송 

포그라운드 

 콜백이 메시지를 처리 


클라이언트 앱 OS 별 콜백 처리

IOS

 didReceiveRemoteNotification:

Android

 onMessageReceived()

 Web 및 자바스크립트

 onMessage()


미리 정의된 키의 전체 목록 참조 문서 


다음 주제는 Firebase 프로젝트 생성과 Android Studio를 이용하여 앱에 FCM 설정하고 
Firebase 콘솔에서 메시지를 발송한 다음 애뮬레이터를 통하여 메시지가 수신이 되는지 확인한다. 


Posted by 사용자 피랑이

댓글을 달아 주세요