먼저 Firebase 프로젝트를 만들어줍니다.
Firebase 프로젝트 만들기
Firebase에서는 Firebase AdminSDK, HTTP v1 API, HTTP, XMPP 등의 방법으로 FCM서버와 통신을 할 수 있습니다.
여기서는 Firebase에서 추천하는 방식인 AdminSDK를 서버에 추가하는 방식으로 해보겠습니다.
gradle
dependencies { implementation 'com.google.firebase:firebase-admin:8.2.0' }
maven
<dependency> <groupId>com.google.firebase</groupId> <artifactId>firebase-admin</artifactId> <version>8.2.0</version> </dependency>
먼저 Firebase콘솔에 가서(프로젝트를 만든 곳) 위에서 만든 프로젝트설정에서 비공개키(.JSON)를 저장해줍니다.
서비스 계정의 비공개 키 파일을 생성하려면 다음 안내를 따르세요.
1. Firebase Console에서 설정 > 서비스 계정을 엽니다.
2. 새 비공개 키 생성을 클릭한 다음 키 생성을 클릭하여 확인합니다.
3. 키가 들어 있는 JSON 파일을 안전하게 저장합니다.
저장한 비공개 키를 설정하는 방법은 2가지가 있습니다.
1. 환경변수를 설정해주는 방법(보안상 더 좋습니다.)
리눅스 or MacOS
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
윈도우
$env:GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"
이렇게 설정한 뒤에 아래처럼 코드를 작성한다. (1부분은 생략가능)
FirebaseOptions options = FirebaseOptions.builder() .setCredentials(GoogleCredentials.getApplicationDefault()) .setDatabaseUrl("https://<DATABASE_NAME>.firebaseio.com/") //1 .build(); FirebaseApp.initializeApp(options);
private static final String FIREBASE_CONFIG_PATH = "본인의 비공개키.json"; //1 @PostConstruct //2 public void initialize() { try { FirebaseOptions options = new FirebaseOptions.Builder() .setCredentials(GoogleCredentials.fromStream(new ClassPathResource(FIREBASE_CONFIG_PATH).getInputStream())).build(); if (FirebaseApp.getApps().isEmpty()) { FirebaseApp.initializeApp(options); } } catch (IOException e) { logger.error(e.getMessage()); } }
//1 -> 본인의 비공캐키 부분을 위에서 받은 JSON형식의 비공개키 파일명을 넣어줍니다.(경로는 보통 src/main/resources)
//2 -> PostConstruct를 넣어주면 의존성 주입이 이루어진 후 초기화를 수행해줍니다. 다른 리소스에서 호출되지 않아도 수행됩니다.
여기서 중요한 키포인트 중 하나는 FirebaseApp이 두번 호출되면 에러가 발생하게 되기때문에 초기화부분은 따로 클래스를 만들어 주는것이 좋습니다.
(Push구현 코드와 초기화코드를 모두 Service단에 작성하였을때
계속 오류가 나서 SDK초기화 부분과 service부분을 분리하니 문제없이 잘 돌아갔습니다.)_
//Message작성 //1 List<Message> messages = tokenList.stream().map(token -> Message.builder() .putData("time", LocalDateTime.now().toString()) .setNotification(Notification.builder() .setTitle("제목") .setBody("내용") .build()) .setToken("알림받을 사람의 토큰") .build()).collect(Collectors.toList()); BatchResponse response; try { //메시지 발송 response = FirebaseMessaging.getInstance().sendAll(messages); //응답처리 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(tokenList.get(i)); } } } } catch(FirebaseMessagingException e) { log.error("cannot send to memberList push message. error info : ()", e.getMessage()); } log.info("Push(Token) 발송!"); }
//1에서 메시지 형식은 다음과 같습니다.
JSON 표현
{ "name": string, "data": { string: string, ... }, "notification": { object (Notification) }, "android": { object (AndroidConfig) }, "webpush": { object (WebpushConfig) }, "apns": { object (ApnsConfig) }, "fcm_options": { object (FcmOptions) }, // Union field target can be only one of the following: "token": string, "topic": string, "condition": string // End of list of possible types for union field target. }
Github 링크
Firebase 공식문서
Firebase Github
backtony님 블로그
애정코딩 블로그