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 |