Java/Spring

[Java] Firebase Cloud Message(FCM) 푸시 메시지 API

조각남자 2024. 8. 26. 15:35

 

💡 Spring Validation 구성을 위한 사용된 개발환경 입니다

 

개발 환경 버전
java 17
Spring Boot 3.3.3
빌드관리도구 Gradle 8.8
개발 툴 IntelliJ IDEA 2024.1
spring-boot-starter-validation 3.3.3



 

1 ) Firebase 설정


 

💡 Firebase 환경설정

- 아래의 공식 사이트에 접근하여 환경설정을 수행합니다.

https://console.firebase.google.com/

 

로그인 - Google 계정

이메일 또는 휴대전화

accounts.google.com

 

1. 프로젝트 설정 > 서비스 > JAVA > 키 생성 클릭


 

2. 생성된 Json 파일 /resources/fcm 에 파일 옮기기


 

 

 

2 ) Spring 환경 설정


 

1. 의존성 ( depindencies ) 추가

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.google.firebase:firebase-admin:9.3.0'           // 구글 firebase
    implementation 'com.fasterxml.jackson.core:jackson-core'    // jakson
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

 

 

 

1. Controller


@Slf4j
@RestController
@RequiredArgsConstructor
public class FcmController {

  private final FcmService fcmService;

  @PostMapping("/send")
  public ResponseEntity<Integer> pushM(@RequestBody FcmRequest request) {
    log.debug(" == 푸시 메시지를 전송합니다. ");
    int result = fcmService.sendMessage(request);

    return new ResponseEntity<>(1,HttpStatus.OK);
  }
}

 

 

2.Service


@Service
public class FcmService {

  public int sendMessage(FcmRequest request) throws IOException {

    String message = makeMessage(request);
    RestTemplate restTemplate = new RestTemplate();
    /**
     * 추가된 사항 : RestTemplate 이용중 클라이언트의 한글 깨짐 증상에 대한 수정
     * @refernece : https://stackoverflow.com/questions/29392422/how-can-i-tell-resttemplate-to-post-with-utf-8-encoding
     */
    restTemplate.getMessageConverters()
        .add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.set("Authorization", "Bearer " + getAccessToken());

    HttpEntity entity = new HttpEntity<>(message, headers);

    String API_URL = "<https://fcm.googleapis.com/v1/projects/book-review-ab331/messages:send>";
    ResponseEntity response = restTemplate.exchange(API_URL, HttpMethod.POST, entity, String.class);

    System.out.println(response.getStatusCode());

    return response.getStatusCode() == HttpStatus.OK ? 1 : 0;
  }

  /**
   * Firebase Admin SDK의 비공개 키를 참조하여 Bearer 토큰을 발급 받습니다.
   *
   * @return Bearer token
   */
  private String getAccessToken() throws IOException {
    String firebaseConfigPath = "fcm/fcm-key.json";

    GoogleCredentials googleCredentials = GoogleCredentials
        .fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())
        .createScoped(List.of("<https://www.googleapis.com/auth/cloud-platform>"));

    googleCredentials.refreshIfExpired();
    return googleCredentials.getAccessToken().getTokenValue();
  }

  /**
   * FCM 전송 정보를 기반으로 메시지를 구성합니다. (Object -> String)
   *
   * @param fcmSendDto FcmSendDto
   * @return String
   */
  private String makeMessage(FcmRequest fcmSendDto) throws JsonProcessingException {

    ObjectMapper om = new ObjectMapper();
    FcmMessageDto fcmMessageDto = FcmMessageDto.builder()
        .message(FcmMessageDto.Message.builder()
            .token(fcmSendDto.getToken())
            .notification(FcmMessageDto.Notification.builder()
                .title(fcmSendDto.getTitle())
                .body(fcmSendDto.getBody())
                .image(null)
                .build()
            ).build()).validateOnly(false).build();

    return om.writeValueAsString(fcmMessageDto);
  }
}

 

 

3. Server ( Flutter ) Token

 

https://github.com/eoog/blog/tree/main/spring-fcm/src/main

 

blog/spring-fcm/src/main at main · eoog/blog

:seedling: 조각남자 티스토리 블로그 기록 내용. Contribute to eoog/blog development by creating an account on GitHub.

github.com