๊ธฐํƒ€

FCM PUSH(IOS) - Java HTTP v1 ์‚ฌ์šฉํ•˜์—ฌ PUSH ์•Œ๋ฆผ ์ ์šฉํ•˜๊ธฐ

์• ์ •์“ฐ 2021. 1. 20. 08:27

FCM PUSH(IOS) - Java Spring Boot Server HTTP v1 ์‚ฌ์šฉํ•˜์—ฌ PUSH ์•Œ๋ฆผ ์ ์šฉํ•˜๊ธฐ

 

๋“œ๋””์–ด ๋งˆ๋ฌด๋ฆฌ ๋‹จ๊ณ„์— ์ ‘์–ด๋“ค์–ด PUSH๋ฅผ ์ ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

ํšŒ์‚ฌ์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ PUSHY๋Š” ์ค‘๊ตญ์„œ๋น„์Šค์—์„œ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—

์ด๋ฒˆ์—๋Š” FCM์„ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค. 

 

๊ณต์‹๋ฌธ์„œ๋Š” ์•„๋ž˜์—์„œ ํ™•์ธ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

firebase.google.com/docs/cloud-messaging/migrate-v1?authuser=0

 

JAVA ์„œ๋ฒ„์—์„œ ์ ์šฉํ•˜๋Š” ๋‚ด์šฉ์ž„์„ ์•Œ๋ ค๋“œ๋ฆฝ๋‹ˆ๋‹ค! ํ”„๋ก ํŠธ์—์„œ ์„ค์ •ํ•ด์ฃผ๋Š” ๋ถ€๋ถ„์€ ๋”ฐ๋กœ ์žˆ์Šต๋‹ˆ๋‹ค!

 

์šฐ์„  ํ”„๋ก ํŠธ์—์„œ ํŒŒ์ด๋ฒ„๋ฒ ์ด์Šค ์ž‘์—…์ด ๋๋‚ฌ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์•ฑ์ถ”๊ฐ€๋œ ํ”„๋กœ์ ํŠธ์ด๋ฆ„ ํด๋ฆญ  - ํ†ฑ๋‹ˆ๋ฐ”ํ€ด ๋ชจ์–‘ ํด๋ฆญํ•˜์—ฌ ํ”„๋กœ์ ํŠธ ์„ค์ •์œผ๋กœ ๋“ค์–ด๊ฐ€์„ธ์š”

 

์ด ์„ค์ •์•ˆ์—์„œ json ํŒŒ์ผ์„ ๋‹ค์šด๋ฐ›์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ ์•ˆ์— ํ•„์š”ํ•œ key๊ฐ’๋“ค์ด ์žˆ์œผ๋‹ˆ ๋…ธ์ถœ๋˜์ง€ ์•Š๋„๋ก ์กฐ์‹ฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค!

 

๊ทธ๋ฆฌ๊ณ  ์ด ํŒŒ์ผ์„ src-main-resources ์•ˆ์— ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  application.yml์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ ํ•ด์ค๋‹ˆ๋‹ค.

    // FCM push
    implementation 'com.google.firebase:firebase-admin:6.8.1'

    //okhttp3
    implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.2.2'

 

okhttp3 ๋Š” APIํ†ต์‹ ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค ๋‚ด์— ์ดˆ๊ธฐํ™”๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค!

๋™๊ธฐ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด execute๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. clinet.newCall()์•ˆ์— Request ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค. 

๊ณต์‹๋ฌธ์„œ


OkHttpClient client = new OkHttpClient();
  
try {
	Response response = client.newCall(request).execute();
	String message = response.body().string();
	System.out.println(message);
 } catch (IOException e) {
    System.err.println(e.toString());
 }
 

Request๋Š” ์ด๋Ÿฐ ๋ฐฉ์‹์œผ๋กœ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค 

	// message๋Š” ๋ฐ‘์—์„œ ๋งŒ๋“ค๊ฒ๋‹ˆ๋‹ค!
	RequestBody requestBody =
        RequestBody.create(message, MediaType.get("application/json; charset=utf-8"));
    
    Request request =
        new Request.Builder()
            .url(API_URL)
            .post(requestBody)
            .addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken())
            .build();

API_URL์€  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋„ฃ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

POST https://fcm.googleapis.com/v1/{parent=projects/*}/messages:send

 

getAccessToken ๋ฉ”์„œ๋“œ๋Š”

  private String getAccessToken() throws IOException {
    GoogleCredentials googleCredentials =
        GoogleCredentials.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())
            .createScoped(List.of("https://www.googleapis.com/auth/cloud-platform"));
    googleCredentials.refreshIfExpired();
    return googleCredentials.getAccessToken().getTokenValue();
  }

์—ฌ๊ธฐ์„œ firebaseConfigPath๋Š” ์•„๊นŒ ๋ฐ›์€ json ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ์ ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ €๋Š” ๋”ฐ๋กœ resources์•ˆ์— ํด๋”๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋„ฃ์ง€์•Š์•„์„œ ํŒŒ์ผ ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ๋„ฃ์–ด์คฌ์Šต๋‹ˆ๋‹ค!

 

์ด์ œ ๋ฉ”์‹œ์ง€๋ฅผ ๋งŒ๋“ค์–ด์ค„๊ฒ๋‹ˆ๋‹ค! 

package com.tickettaca.commons.firebase.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Builder
@AllArgsConstructor
@Getter
public class NotificationRequest {

  private boolean validate_only;
  private Message message;

  @Builder
  @AllArgsConstructor
  @Getter
  public static class Apns{
    private Payload payload;

  }
  @Builder
  @AllArgsConstructor
  @Getter
  public static class Payload{
    private Aps aps;

  }
  @Builder
  @AllArgsConstructor
  @Getter
  public static class Aps{
    private String sound;
  }

  @Builder
  @AllArgsConstructor
  @Getter
  public static class Message {
    private Notification notification;
    private String token;
    private Apns apns;
  }

  @Builder
  @AllArgsConstructor
  @Getter
  public static class Notification {
    private String title;
    private String body;
    private String image;
  }

}
private String makeMessage(String pushToken, String title, String body) {

    NotificationRequest fcmMessage =
        NotificationRequest.builder()
            .message(
                NotificationRequest.Message.builder()
                    .token(pushToken)
                    .notification(
                        NotificationRequest.Notification.builder()
                            .title(title)
                            .body(body)
                            .image(null)
                            .build())
                    .apns(
                        NotificationRequest.Apns.builder()
                            .payload(
                                NotificationRequest.Payload.builder()
                                    .aps(NotificationRequest.Aps.builder().sound("default").build())
                                    .build())
                            .build())
                    .build())
            .validate_only(false)
            .build();
    

    String fcmMessageString = "";

    try {
      fcmMessageString = objectMapper.writeValueAsString(fcmMessage);
    } catch (JsonProcessingException e) {
      e.printStackTrace();
    }

    return fcmMessageString;
  }

 

๊ณต์‹๋ฌธ์„œ์—์„œ ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ช…์„ dto์— ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ณต์‹๋ฌธ์„œ์—์„œ ํ™•์ธํ•œ ๋ถ€๋ถ„์€ ์• ํ”Œ์ผ ๊ฒฝ์šฐ ์†Œ๋ฆฌ๋ฅด ๋”ฐ๋กœ ์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ์ง„๋™๋„ ์†Œ๋ฆฌ๋„ ์•ˆ๋‚˜๋Š” ๋งˆ๋ฒ•,, ์œ„ ์ฝ”๋“œ์—์„œ apns ๊ฐ€ ์ง„๋™์ด๋‚˜ ์†Œ๋ฆฌ๋ฅผ ๋‚ด์ฃผ๋Š” ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. default๋กœ ์ •ํ•ด๋‘๋ฉด ์•„์ดํฐ ๊ธฐ๋ณธ์Œ์œผ๋กœ ์ „์†ก์ด ๋ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์ธ ๋ฉ”์‹œ์ง€ ์ „์†ก ๋ฐฉ๋ฒ•์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋“ค์€ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”!

 

ํ˜น์‹œ ๋ชฐ๋ผ์„œ ์‚ฌ์šฉ๋ฒ•๋„ ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค! \u ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ฌธ์ž๋Š” ์ด๋ชจํ‹ฐ์ฝ˜ ์ž…๋‹ˆ๋‹ค^.^

 private final FCMService fcmService;
 
 fcmService.sendMessageTo(
        lover.getPushToken(),
        user.getName() + "์ด(๊ฐ€) ์ฟ ํฐ์„ ์‚ฌ์šฉํ•˜์…จ์Šต๋‹ˆ๋‹ค. \uD83D\uDE03",
        couponEntity.getBookEntity().getName());
๋ฐ˜์‘ํ˜•