FCM으로 앱에 push알림 보내기

이상진·2022년 6월 20일
0
post-thumbnail

FCM이란?

  • Firebase Cloud Messaging의 약자로, 무료로 메시지(알림, 인앱메시지 등)를 안정적으로 전송할 수 잇는 교차 플랫폼 메시징 솔루션입니다.
  • 모든 사용자에게 알림메시지를 전송할 수도 있고, 그룹별, 주제별로 메시지를 전송할 수도 있습니다.

FCM의 장점

  • 교차플랫폼을 지원하기때문에 IOS , Android, Web까지 한번에 메시지를 보낼수 있다.
  • 직접 구현 하게 되면 서버를 거쳐서 메시지를 보내기때문에 항상 서버에 접속해야하지만(배터리,네트워크 이슈발생) FCM을 이용하면 중간에 클라우드 메시징 서버를 두는 방식으로 필요할때만 접속하게 된다.
  • 무료이다.

PUSH알림 만들기

1. 프로젝트 만들기

먼저 Firebase 프로젝트를 만들어줍니다.
Firebase 프로젝트 만들기

2. SDK추가

Firebase에서는 Firebase AdminSDK, HTTP v1 API, HTTP, XMPP 등의 방법으로 FCM서버와 통신을 할 수 있습니다.
여기서는 Firebase에서 추천하는 방식인 AdminSDK를 서버에 추가하는 방식으로 해보겠습니다.

  • 스프링에 SDK를 추가해줍니다.
    (gradle은 build.gradle, maven은 pom.xml)

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>

3. SDK 초기화

  • 먼저 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);
  1. 코드에서 JSON파일의 경로를 명시해주는 방법
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부분을 분리하니 문제없이 잘 돌아갔습니다.)_

4. Push 구현

//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.
}
  • 자세한 내용은 링크를 통해 확인하실 수 있습니다.
  • 코드 작성후 실행해보면 Push가 잘 들어오는 것을 확인 할 수 있다.

참고자료

Github 링크
Firebase 공식문서
Firebase Github
backtony님 블로그
애정코딩 블로그

profile
Back-end Engineer

0개의 댓글