HEROJOON 블로그(히로블)
FCM 서버 프로토콜을 이용한 Push 전송 본문
2020/02/24 - [Backend] - FCM 시작하기
2020/02/24 - [Backend] - Android Studio 환경 셋업
2020/02/28 - [Backend] - Android 앱 프로젝트에 Firebase설정
2020/02/28 - [Backend] - Android 앱 프로젝트에 FCM설정 및 코드작성
2020/02/24 - [Backend] - Firebase Push전송 구현을 위한 준비
2021.08.15 - [Backend] - Push 전송 프로젝트 생성
2020/03/05 - [Backend] - Firebase Admin SDK를 이용한 Push 전송
4. FCM Push발송 API Server 프로젝트 생성 (Sender)
4-1. Firebase Push전송 구현을 위한 준비
4-2. Push 전송 프로젝트 생성
4-3. Firebase Admin SDK를 이용한 Push 전송
4-4. FCM 서버 프로토콜을 이용한 Push 전송
- FCM 서버 엔드포인트
- FCM 서버 프로토콜 인증
- Push 발송 API 구현 - 특정 기기에 메시지 전송
목표
이 글의 목표는 FCM 서버 프로토콜을 이용하여 Android 앱에 Push를 전송하는 것이다.
(참고 docs : https://firebase.google.com/docs/cloud-messaging/migrate-v1?authuser=1)
FCM 서버 엔드포인트
HTTP Protocol을 이용하여 FCM메시지를 전송할 경우 FCM에서 제공하는 서버 엔드포인트가 필요합니다.
Push Sender는 이 FCM 엔드포인트 API로 메시지 전송하고, 전송된 메시지는 FCM으로 전달되어 최종적으로 안드로이드앱에 Push가 전송되는 Flow입니다.
FCM 서버 엔드포인트에 대한 설명은 위 참고 docs를 참고하시면 됩니다.
FCM 서버 엔드포인트의 형식은
POST https://fcm.googleapis.com/v1/projects/{프로젝트ID}/messages:send
입니다.
프로젝트ID는 Firebase 콘솔화면 - 앱관리 화면에서 확인 가능합니다.
FCM 서버 프로토콜 인증
FCM 서버 프로토콜을 이용해서 Push 전송 시, 인증을 위하여 AccessToken이 필요합니다.
AccessToken을 얻기 위한 가이드는 위 참고 docs에서 [사용자 인증 정보를 사용하여 액세스 토큰 발급]을 참고하시면 됩니다.
service-account.json이라는 사용자 인증정보를 사용하여 액세스 토큰을 발급받을 수 있습니다.
(service-account.json을 얻는 방법은
2020/03/05 - [Backend] - Firebase Admin SDK를 이용한 Push 전송
를 참고해주세요.)
Push 발송 API 구현 - 특정 기기에 메시지 전송
FCM 서버 프로토콜을 이용하여 Push 전송 정리
1) 서버 엔드포인트와 (FCM 서버 프로토콜 API)
POST https://fcm.googleapis.com/v1/projects/{프로젝트ID}/messages:send
2) AccessToken을 이용해서 (인증을 위한 값)
사용자 인증정보(service-account.json)에서 얻은 AccessToken
3) 특정 기기에
특정 기기 token정보에 메시지 전송
(토큰 얻는 방법은
2020/02/28 - [Backend] - Android 앱 프로젝트에 FCM설정 및 코드작성
를 참고해주세요.)
4) 메시지 정보를
메시지 포맷은 위 참고 docs를 참고하시면 됩니다. 저는 아래 메시지 포맷으로 보내도록 하겠습니다.
{"message":{"data":{"title":"메시지를 보낼거야2","content":"너에게로2"},"token":"특정 기기 토큰정보"}}
보내면 됩니다.
코드작성 (by herojoon)
1) Controller 작성
package com.herojoon.pushsender.controller;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import okhttp3.*;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
@RestController
@RequestMapping("push")
public class PushController {
private static final String MESSAGING_SCOPE = "https://www.googleapis.com/auth/firebase.messaging";
private static final String[] SCOPES = { MESSAGING_SCOPE };
@Value("${fcm.devicetoken}")
private String FCM_DEVICE_TOKEN;
@Value("${fcm.apiurl}")
private String FCM_API_URL;
/**
* HTTP Protocol을 이용한 Push 전송
* @return
*/
@RequestMapping("/send")
public void send() {
// 1. create message body
JSONObject jsonValue = new JSONObject();
jsonValue.put("title", "메시지를 보낼거야2");
jsonValue.put("content", "너에게로2");
JSONObject jsonData = new JSONObject();
jsonData.put("token", FCM_DEVICE_TOKEN);
jsonData.put("data", jsonValue);
JSONObject jsonMessage = new JSONObject();
jsonMessage.put("message", jsonData);
// 2. create token & send push
try {
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.addHeader("Authorization", "Bearer " + getAccessToken())
.addHeader("Content-Type", "application/json; UTF-8")
.url(FCM_API_URL)
.post(RequestBody.create(jsonMessage.toString(), MediaType.parse("application/json")))
.build();
Response response = okHttpClient.newCall(request).execute();
System.out.println("### response str : " + response.toString());
System.out.println("### response result : " + response.isSuccessful());
} catch (Exception e) {
e.printStackTrace();
}
}
private static String getAccessToken() throws IOException {
ClassPathResource resource = new ClassPathResource("keystore/service-account.json");
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream(resource.getFile()))
.createScoped(Arrays.asList(SCOPES));
googleCredential.refreshToken();
return googleCredential.getAccessToken();
}
}
2) build.gradle 추가
compile group: 'org.json', name: 'json', version: '20190722'
compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.2.2'
'Backend' 카테고리의 다른 글
Android [Service took too long to process intent: com.google.android.c2dm.intent.RECEIVE App may get closed.]해결하기 (0) | 2020.03.17 |
---|---|
Spring Boot 프로젝트에서 Vuejs 한번에 빌드하기 (11) | 2020.03.16 |
Firebase Admin SDK를 이용한 Push 전송 (0) | 2020.03.05 |
성능 테스트 시 고려할 점 (0) | 2020.03.04 |
Android 앱 프로젝트에 FCM설정 및 코드작성 (0) | 2020.02.28 |