기나긴 "한성대학교 기자재 대여 통합 시스템" 개발의 마지막 단계
FCM기능을 구축해 보았다.
"한성대학교 기자재 대여 통합 시스템" 개발팀의 자문을 맡은게 22년도 2월이고, 본격적으로 준팀장으로 개발에 참여한게 5월부터니, 3개월에 걸친 개발도 끝을 향해 달려가고 있다.
아무튼,
파이어베이스에서 해당기기로 푸시알림을 보낼 수 있는 서비스가 있는데, 그것을 이용하여
신청한 기자재가 관리자에 의해 승인이 났을 때 승인 완료 알림을 주고 싶었다.
그것을 구축했고, 테스트까지 성공하였다. 이제 그 방법을 포스팅하겠다.
#1 FCMMessage
우선, 데이터를 통신하기 위해 기준이 되는 클래스인 DTO를 만든다.
이부분은 Firebase Cloud Message 공식문서에 잘 나와있다.
https://firebase.google.com/docs/cloud-messaging/
Firebase 클라우드 메시징 | Firebase 문서
Firebase 클라우드 메시징(FCM)은 무료로 메시지를 안정적으로 전송할 수 있는 크로스 플랫폼 메시징 솔루션입니다.
firebase.google.com
package controller;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
@Builder
@AllArgsConstructor
@Getter
public class FCMMessage {
private boolean validate_only;
private Message message;
@Builder
@AllArgsConstructor
@Getter
public static class Message {
private Notification notification;
private String token;
}
@Builder
@AllArgsConstructor
@Getter
public static class Notification {
private String title;
private String body;
private String image;
}
#2 FCMService
package controller;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.api.client.util.Value;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.net.HttpHeaders;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.messaging.*;
import lombok.RequiredArgsConstructor;
import okhttp3.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@Component
@RequiredArgsConstructor
public class FCMService {
@Value("${project.properties.firebase-create-scoped}")
String fireBaseCreateScoped;
private FirebaseMessaging instance;
private final String API_URL = "https://fcm.googleapis.com/v1/projects/*프로젝트id*/messages:send";
private ObjectMapper objectMapper = new ObjectMapper();
public void sendMessageTo(String targetToken, String title, String body) throws IOException {
String message = makeMessage(targetToken, title, body);
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(message, MediaType.get("application/json; charset=utf-8"));
Request request = new Request.Builder()
.url(API_URL)
.post((okhttp3.RequestBody) requestBody)
.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken())
.addHeader(HttpHeaders.CONTENT_TYPE, "application/json; UTF-8")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
private String makeMessage(String targetToken, String title, String body) throws JsonParseException, JsonProcessingException {
FCMMessage fcmMessage = FCMMessage.builder()
.message(FCMMessage.Message.builder()
.token(targetToken)
.notification(FCMMessage.Notification.builder()
.title(title)
.body(body)
.image(null)
.build()
).build()).validate_only(false).build();
return objectMapper.writeValueAsString(fcmMessage);
}
private String getAccessToken() throws IOException {
String firebaseConfigPath = "키파일 경로";
GoogleCredentials googleCredentials = GoogleCredentials
.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())
.createScoped(List.of("https://www.googleapis.com/auth/cloud-platform"));
googleCredentials.refreshIfExpired();
return googleCredentials.getAccessToken().getTokenValue();
}
}
그 후 서비스를 공식문서와 구글링을 통해 구현하고 간단하게 테스트를 하였다.
makeMessage는 아까 정의했던 DTO를 이용해 FCM서버에 전달할 내용을 만들고,
sendMessageTo는 만들어진 메세지를 HTTP POST로 FCM서버에 메세지 전송을 요청한다.
getAccessToken은 FCM을 수신받거나 할 때 쓰는 토큰이 아닌, FCM서버에 전송을 요청하기 위한 권한을 얻기위해 존재하는 토큰이다.
이제 테스트를해보자.
로컬서버를 먼저 키고
POSTMAN을 이용해 서버에 POST전송을 하고 다시 로컬서버 로그에 가보면
이런 형식으로 떳다면 전송이 성공한 것이다.
만약 실패했다면 403에러가 뜨고 왜 에러가 난 것인지 착하게 로그로 알려주니 로그를 분석하면서 에러를 잡으면 된다.
최종적으로 전송이 완료되면 이렇게 빠라바밤 하는 알림소리와 함께 알림이 잘 온다.
당연히 안드로이드에서도 해당 알람을 받는 코드를 작성해야한다.
iOS까지 작성할걸 생각하니 머리가 아파온다
안드로이드와 iOS포스팅은 다음에 작성하도록 하겠다.
이제 이걸 바탕으로 원하는 시기에 원하는 내용의 알람을 전송하는 코드를 짜러 가야겠다.
오늘도 배워가는 즐거움을 느끼며
이만 빠잉!
'Web > Spring' 카테고리의 다른 글
Spring : Lagacy 프로젝트에서 FCM Web Push 수신을 받아보았다. (0) | 2022.12.17 |
---|---|
Spring : POST 동적 생성 (0) | 2022.09.28 |
Spring : MySQL 다중 쿼리를 해봤다. (0) | 2022.08.05 |
Spring : 스프링 Github 프로젝트 시 .gitignore설정 (0) | 2022.07.24 |
Spring : 이미지를 MySQL에 저장하고 출력 해봤다 (0) | 2022.07.22 |