fcm:
key:
path: filePath*.json
scope: https://www.googleapis.com/auth/firebase.messageing
// firebase FCM
implementation 'com.google.firebase:firebase-admin:9.1.1'
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class FirebaseMessageService {
@Value("${fcm.key.path}")
private String PATH;
...
// fcm 멀티 알림 옵션 생성
private void firebaseCreateOption() throws IOException {
FileInputStream refreshToken = new FileInputStream(PATH);
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(refreshToken))
.build();
FirebaseApp.initializeApp(options);
}
/**
* 전체 알림 메시지
*
* @param title
* @param body
* @return
* @throws IOException
* @throws FirebaseMessagingException
*/
public ApiResult notificationAlarm(String title, String body, List<String> tokenList) throws IOException, FirebaseMessagingException {
firebaseCreateOption();
// fcm multiMessage 객체 생성 하여 보냄
MulticastMessage message = MulticastMessage.builder()
.putData("fcm_type", "NOTIFICATION") // 알람 종류 타입
.putData("title", title)
.putData("body", body)
.addAllTokens(tokenList)
// .addToken(token) // 단일 토큰일 경우
.build();
BatchResponse response = FirebaseMessaging.getInstance().sendMulticast(message);
failMessage(tokenList, response);
return ApiUtils.success("message", ComCode.ALARM_SUCCESS, ComCode.SUCCESS_CODE);
}
MulticastMessage 를 빌더로 생성함
putData는 알림 메시지 데이터를 넣는다고 보면 된다.
token list 로 단체 알림을 보낼수도 있고
addToken으로 단건으로 보낼수 있다.
MulticastMessage 생성하고 난 뒤 sendMulticast(message)로 담아 보낸다.
보내고 난 뒤 응답 response는 실패한 fcm 토큰값을 따로 걸러내기 위한 용도이다.
failMessage() 밑에 함수를 보고 다시 설명하겠다.
// 토큰이 유효하지 않아서 fcm 발송이 실패한 데이터 추출
private void failMessage(List<String> mergeTokenList, BatchResponse response) {
if (response.getFailureCount() > 0) {
List<SendResponse> responses = response.getResponses();
List<String> failedTokens = new ArrayList<>();
for (int i = 0; i < responses.size(); i++) {
if (!responses.get(i).isSuccessful()) {
failedTokens.add(mergeTokenList.get(i));
}
}
log.info("======================= failedTokens : " + failedTokens + "=======================(추후 실패한 토큰은 삭제 시켜줘야함) -> 쓸데없는 알람이 가서 성능 저하를 일으킴");
}
log.info("======================= Success : " + response + "=======================");
}
실패한 토큰값은 추후에 성능저하를 일으킨다는 블로그를 보아
로직을 만들어 봤다.