From 69dbe3a3fe37f4ad39bdbbe7335627949158285f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EA=B1=B4=ED=9A=8C?= Date: Mon, 22 Jan 2024 17:25:24 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20fcm=20sdk=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?=EB=B0=8F=20fcm=20=EC=84=9C=EB=B2=84=EC=B8=A1=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=EC=B2=98=EB=A6=AC=20=EB=B9=84=EB=8F=99=EA=B8=B0=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pium/admin/ui/TestController.java | 31 +++-- .../fcm/application/FcmMessageSender.java | 117 ++++++++++++------ 2 files changed, 94 insertions(+), 54 deletions(-) diff --git a/backend/pium/src/main/java/com/official/pium/admin/ui/TestController.java b/backend/pium/src/main/java/com/official/pium/admin/ui/TestController.java index 555d26df..e40fdfcf 100644 --- a/backend/pium/src/main/java/com/official/pium/admin/ui/TestController.java +++ b/backend/pium/src/main/java/com/official/pium/admin/ui/TestController.java @@ -1,6 +1,9 @@ package com.official.pium.admin.ui; +import com.official.pium.admin.service.TestService; import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -9,23 +12,17 @@ @RequestMapping("/test") public class TestController { -// private final TestService testService; + private final TestService testService; -// @GetMapping("/notifications") -// public ResponseEntity notificationTest() { -// testService.sendWaterNotificationTest(); -// return ResponseEntity.ok("알림 기능 테스트 성공"); -// } + @GetMapping("/notifications/ramp") + public ResponseEntity notificationRampTest() { + testService.sendWaterNotificationAsyncRampTest(); + return ResponseEntity.ok("비동기 알림 기능 테스트 램프업 성공"); + } -// @GetMapping("/notifications/ramp") -// public ResponseEntity notificationRampTest() { -// testService.sendWaterNotificationAsyncRampTest(); -// return ResponseEntity.ok("비동기 알림 기능 테스트 램프업 성공"); -// } -// -// @GetMapping("/notifications/async") -// public ResponseEntity notificationAsyncTest() { -// testService.sendWaterNotificationAsyncTest(); -// return ResponseEntity.ok("비동기 알림 기능 테스트 성공"); -// } + @GetMapping("/notifications/async") + public ResponseEntity notificationAsyncTest() { + testService.sendWaterNotificationAsyncTest(); + return ResponseEntity.ok("비동기 알림 기능 테스트 성공"); + } } diff --git a/backend/pium/src/main/java/com/official/pium/notification/fcm/application/FcmMessageSender.java b/backend/pium/src/main/java/com/official/pium/notification/fcm/application/FcmMessageSender.java index a595c90b..7f49161d 100644 --- a/backend/pium/src/main/java/com/official/pium/notification/fcm/application/FcmMessageSender.java +++ b/backend/pium/src/main/java/com/official/pium/notification/fcm/application/FcmMessageSender.java @@ -1,25 +1,32 @@ package com.official.pium.notification.fcm.application; import com.google.auth.oauth2.GoogleCredentials; -import com.official.pium.notification.fcm.dto.FcmMessageResponse; -import com.official.pium.notification.fcm.exception.FcmException; +import com.google.firebase.FirebaseApp; +import com.google.firebase.FirebaseOptions; +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.Message; +import com.google.firebase.messaging.Notification; import com.official.pium.notification.application.MessageSendManager; +import com.official.pium.notification.fcm.dto.FcmMessageResponse; +import jakarta.annotation.PostConstruct; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.concurrent.ExecutionException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; -import java.io.IOException; @Slf4j @Component @RequiredArgsConstructor public class FcmMessageSender implements MessageSendManager { + private static final String JSON_FILE_PATH = "src/main/resources/config/pium-fcm.json"; + @Value("${fcm.api.url}") private String apiUrl; @@ -31,50 +38,86 @@ public class FcmMessageSender implements MessageSendManager { private final RestTemplate restTemplate; - public void sendMessageTo(String targetToken, String title, String body) { + @PostConstruct + public void initialize() { + FileInputStream serviceAccount; try { - FcmMessageResponse message = makeMessage(targetToken, title, body); - - HttpHeaders headers = new HttpHeaders(); - headers.set(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken()); - headers.set(HttpHeaders.CONTENT_TYPE, "application/json; UTF-8"); - - HttpEntity request = new HttpEntity<>(message, headers); - - ResponseEntity postResult = restTemplate.postForEntity( - apiUrl, - request, - FcmMessageResponse.class - ); + serviceAccount = new FileInputStream(JSON_FILE_PATH); + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(GoogleCredentials.fromStream(serviceAccount)) + .build(); - log.info("FCM 메시지 전송 성공: {}", postResult.getBody()); + FirebaseApp.initializeApp(options); + } catch (FileNotFoundException e) { + log.error("파일을 찾을 수 없습니다. " + e); + } catch (IOException e) { + log.error("FCM 인증이 실패했습니다. " + e); + } + } - } catch (Exception e) { - log.error("FCM 메시지 전송 실패", e); - throw new FcmException.FcmMessageSendException(e.getMessage()); + public void sendMessageTo(String targetToken, String title, String body) { + Notification notification = Notification.builder() + .setTitle(title) + .setBody(body) + .build(); + Message message = Message.builder() + .setToken(targetToken) + .setNotification(notification) + .build(); + try { + String response = FirebaseMessaging.getInstance().sendAsync(message).get(); + log.info("응답 결과 : " + response); + } catch (InterruptedException e) { + log.error(e.getMessage()); + } catch (ExecutionException e) { + log.error(e.getMessage()); } } +// public void sendMessageTo(String targetToken, String title, String body) { +// try { +// FcmMessageResponse message = makeMessage(targetToken, title, body); +// +// HttpHeaders headers = new HttpHeaders(); +// headers.set(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken()); +// headers.set(HttpHeaders.CONTENT_TYPE, "application/json; UTF-8"); +// +// HttpEntity request = new HttpEntity<>(message, headers); +// +// ResponseEntity postResult = restTemplate.postForEntity( +// apiUrl, +// request, +// FcmMessageResponse.class +// ); +// +// log.info("FCM 메시지 전송 성공: {}", postResult.getBody()); +// +// } catch (Exception e) { +// log.error("FCM 메시지 전송 실패", e); +// throw new FcmException.FcmMessageSendException(e.getMessage()); +// } +// } + private FcmMessageResponse makeMessage(String targetToken, String title, String body) { return FcmMessageResponse.builder() - .message(FcmMessageResponse.Message.builder() - .token(targetToken) - .notification(FcmMessageResponse.Notification.builder() - .title(title) - .body(body) - .image(null) - .build() - ) - .build() + .message(FcmMessageResponse.Message.builder() + .token(targetToken) + .notification(FcmMessageResponse.Notification.builder() + .title(title) + .body(body) + .image(null) + .build() ) - .validate_only(false) - .build(); + .build() + ) + .validate_only(false) + .build(); } private String getAccessToken() throws IOException { GoogleCredentials googleCredentials = GoogleCredentials - .fromStream(new ClassPathResource(keyPath).getInputStream()) - .createScoped(keyScope); + .fromStream(new ClassPathResource(keyPath).getInputStream()) + .createScoped(keyScope); googleCredentials.refreshIfExpired(); return googleCredentials.getAccessToken().getTokenValue(); }