FCM 이란

Firebase 클라우드 메시징(FCM)으로 배터리를 절약하면서 서버와 기기를 안정적으로 연결하고, iOS, Android, 웹에서 메시지와 알림을 무료로 주고받을 수 있습니다.

 

curl 발송

curl -X POST --header "Authorization: key=your key" --header "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d '{"to" : "your token",  "priority" : "high",  "notification" : {    "body" : "Background Message",    "title" : "BG Title"  },  "data" : {    "title" : "FG Title",    "message" : "Foreground Message"  }}'

 

Java 구현

1. gradle 라이브러리

// Google FCM
implementation 'com.google.auth:google-auth-library-oauth2-http:1.18.0'
implementation 'com.google.firebase:firebase-admin:9.2.0'

 

  •  Firebase에서 Legacy > HTTP v1으로 방식이 변경되면서 oauth2 인증 방식으로 구현을 하고 있습니다.

2. oauth2 인증 pem 발급

    1. https://firebase.google.com/products/cloud-messaging?hl=ko 에서 프로젝트 생성

    2. 앱등록

    3. 프로젝트 설정 > 서비스 계정 > 새 비공개키 발급

3. Java FirebaseApp 세팅

import java.io.FileInputStream;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.FirebaseApp;


public class AppPush {

	public static void init() {
        Stirng projectId = "[Project Id]"; // 프로젝트 설정 > 일반 > 프로젝트ID
        String oauthPath = "service-oauth.json";
         // Firebase 앱 초기화
        FileInputStream serviceAndroidAccount = null;
        try {
            serviceAndroidAccount = new FileInputStream(oauthPath);
            FirebaseOptions options = new FirebaseOptions.Builder()
                    .setCredentials(GoogleCredentials.fromStream(serviceAndroidAccount))
                    .build();
            FirebaseApp.initializeApp(options);
        } catch (IOException e) {
            log.warn("=============== App Push Setting Failed ==============");
        }
    }
}

 

4. Java 발송

import com.google.firebase.messaging.*;

public class AppPush {

	public static void init() {
        ...
    }
    
    // 안드로이드 단건
    public boolean androidSendPush(String title, String body, String summary
            , String thumbnailURL, String clickAction,  String openAction, String receiveAction, long ttl,
            String token
    ) {

        try {
            Message message = Message.builder()
                    .setToken(token) // Phone Token
                    .setAndroidConfig(
                        AndroidConfig.builder()
                                .setTtl(ttl)
                                .setPriority(AndroidConfig.Priority.HIGH)
                                .putAllData(
                                        PushDataModel.builder()
                                                .title(title)
                                                .body(body)
                                                .summary(summary)
                                                .image(thumbnailURL)
                                                .click_action(clickAction)
                                                .open_action(openAction)
                                                .receive_action(receiveAction)
                                                .build()
                                                .toMap()
                                )
                                .setDirectBootOk(false)
                                .build()
                    )
                    .build();
            String responses = FirebaseMessaging.getInstance().send(message);
            return true;
        } catch (FirebaseMessagingException e) {
        	return false;
   	}
    }
    
    // IOS 단건
    public boolean iosSendPush(
            String title, String body, String summary
            , String thumbnailURL, String clickAction,  String openAction, String receiveAction,
            String token
    ) {
        try {
            Message message = Message.builder()
                    .setToken(token)
                    .putAllData(PushDataModel.builder()
                            .title(title)
                            .body(body)
                            .summary(summary)
                            .image(thumbnailURL)
                            .click_action(clickAction)
                            .open_action(openAction)
                            .receive_action(receiveAction)
                            .build()
                            .toMap()
                    )
                    .setApnsConfig(
                            ApnsConfig.builder()
                                    .setAps(
                                            com.google.firebase.messaging.Aps.builder()
                                                    .setAlert(
                                                            ApsAlert.builder()
                                                                    .setTitle(title)
                                                                    .setBody(body)
                                                                    .setSubtitle(summary)
                                                                    .build()
                                                    )
                                                    .build()
                                    )
                                    .build()
                    )
                    .build();
            String responses = FirebaseMessaging.getInstance().send(message);
            return true;
        } catch (FirebaseMessagingException e) {
                log.error("{}", e.getMessage(), e);
            return false;
        }
    }
	// 안드로이드 다건 
	public Map<String, Boolean> androidSendMulticastPush(
            String title, String body, String summary
            , String thumbnailURL, String clickAction,  String openAction, String receiveAction, long ttl,
            List<String> tokens
            ) {
        Map<String, Boolean> result = new HashMap<>();
        for (String token : tokens) {
            result.put(token, false);
        }

        try {
            MulticastMessage messages = MulticastMessage.builder()
                    .addAllTokens(tokens)
                    .setAndroidConfig(
                            AndroidConfig.builder()
                                    .setTtl(ttl)
                                    .setPriority(AndroidConfig.Priority.HIGH)
                                    .putAllData(
                                            PushDataModel.builder()
                                                    .title(title)
                                                    .body(body)
                                                    .summary(summary)
                                                    .image(thumbnailURL)
                                                    .click_action(clickAction)
                                                    .open_action(openAction)
                                                    .receive_action(receiveAction)
                                                    .build()
                                                    .toMap()
                                    )
                                    .setDirectBootOk(false)
                                    .build()
                    )
                            .build();
            BatchResponse responses = FirebaseMessaging.getInstance().sendEachForMulticast(messages);
            for (int i = 0; i < responses.getResponses().size(); i++) {
                result.put(tokens.get(i), responses.getResponses().get(i).isSuccessful());
            }
            return result;
        } catch (FirebaseMessagingException e) {
            log.error("{}", e.getMessage(), e);
            return result;
        }
    }

	// IOS 다건
    public Map<String, Boolean> iosSendMulticastPush(
            String title, String body, String summary
            , String thumbnailURL, String clickAction,  String openAction, String receiveAction,
            List<String> tokens
    ) {
        Map<String, Boolean> result = new HashMap<>();
        for (String token : tokens) {
            result.put(token, false);
        }

        try {
            MulticastMessage messages = MulticastMessage.builder()
                    .addAllTokens(tokens)
                    .putAllData(PushDataModel.builder()
                            .title(title)
                            .body(body)
                            .summary(summary)
                            .image(thumbnailURL)
                            .click_action(clickAction)
                            .open_action(openAction)
                            .receive_action(receiveAction)
                            .build()
                            .toMap()
                    )
                    .setApnsConfig(
                            ApnsConfig.builder()
                                    .setAps(
                                            com.google.firebase.messaging.Aps.builder()
                                                    .setAlert(
                                                            ApsAlert.builder()
                                                                    .setTitle(title)
                                                                    .setBody(body)
                                                                    .setSubtitle(summary)
                                                                    .build()
                                                    )
                                                    .build()
                                    )
                                    .build()
                    )
                    .build();
            BatchResponse responses = FirebaseMessaging.getInstance().sendEachForMulticast(messages);
            for (int i = 0; i < responses.getResponses().size(); i++) {
                result.put(tokens.get(i), responses.getResponses().get(i).isSuccessful());
            }
            return result;
        } catch (FirebaseMessagingException e) {
            log.error("{}", e.getMessage(), e);
            return result;
        }
    }
}

'Java > Spring' 카테고리의 다른 글

Java Mail  (0) 2023.08.02
[Spring] Rest API 통신 방법 ( RestTemplate vs FeignClient vs WebClient )  (0) 2023.05.05
[Spring] AOP  (0) 2023.03.23
[Spring] MapStruct 적용 방법  (0) 2023.03.21
[AWS] SQS Listener 구축 ( Java + Gradle + Spring )  (1) 2023.03.17

+ Recent posts