진짜 개발자
본문 바로가기

FrameWork/Spring Boot

Spring Boot - FCM Push 서버 구축하기

728x90
test

이번 포스팅에서는, Spring boot와 firebase의 FCM을 이용해, PushNotifiaction Server 구축을 해보도록 하겠습니다. Front는 구현이 되어있다고 가정하고, backend만을 구축하겠습니다.

 

 

 

Push Notification을 위한 개념

1. Push Notification이란

푸시 알림은 Server에서 유저의 device로 정보를 보내는 기술을 일컫는 말입니다.

 

 

예를 들어 위와같이 사용중이지 않은 app에서 오는 알림을 일컫습니다.

 

 

 

2. Push Notification 동작

유저의 device에 push 알림을 보내기 위한 상세 구현은, 모바일 os 마다 다르겠지만 큰틀은 비슷합니다. 우선 PushNotification 과정을 알아보기 이전에, 이 포스팅에서 설명드리기 위해 사용하는 용어를 정리해보겠습니다.

 

용어

Notification Server

GCM, APNs 와 같이, mobile 기기에 Push 알림을 전송하는 서버입니다.

 

Client App

사용자의 mobile기기에 설치된 app을 의미합니다. Push 알림을 받는 역할을 합니다.

 

Provider

Client App을 위한 서버입니다. 필요시 Notification Server에 요청을 전송하여, Client App에 알림을 보냅니다.

 

 

과정

  1. Client App을 Notification Server에 등록합니다.
  2. Client App을 켜면 각각의 Client App을 구분하는 Token 을 Notification Server에서 발급합니다.
  3. Client App에서 이 Token 을 Provider로 전송합니다.
  4. Provider는 Token 을 저장해둡니다.
  5. Client App에 알림을 전송할 필요가 있을때, Token 값과 함께 Notification Server에 요청합니다.
  6. Client App에서 Push 알림을 수신합니다.

저희는, 빠른 구축을 위해서, Token을 저장하는 과정을 생략하고, Front에서 생성된 토큰값을 console에 출력하여, 그 토큰을 바로 사용하도록 하겠습니다.

 

 

 

 

 

Firebase Project 생성

Front에서 FCM을 이용해 푸시알림을 수신하도록 구축하셨다면, 아마도 이미 생성하신 것이 존재 할겁니다. Server에서도 해당 프로젝트를 같이 사용해야하므로, 별도의 프로젝트를 생성하지 않도록 합니다.

 

https://console.firebase.google.com/

프로젝트 생성 과정은 간단하기 때문에 생략합니다.

 

 

 

 

 

Spring Boot Push 알림 서버구축 (HTTP v1 API 이용)

  1. Firebase에 앱서버 인증 (신뢰할 수 있는 서버에서 온 요청인지를 firebase에서 구분하기 위해)
  2. Firebase에 Push 알림 요청 (admin sdk를 이용하지 않고, rest api를 이용)

구축할 서버의 과정은 위와 같이 크게 두가지로 나눌수 있습니다. admin sdk를 이용하여 push 알림을 요청하는 경우 매우 쉽게 요청이 가능하지만, 이번 포스팅에서는 HTTP v1 API 를 이용해 서버를 구축하도록 하겠습니다.

 

 

 

1. Firebase에 앱서버 인증

App Server에서 App으로 Push 알림을 주기위해서는, FCM에 요청을 해야하는데요. 이때, 당연히 App의 진짜 AppServer에서 온 요청에만 FCM이 반응을 해야합니다. 그렇지 않은 경우, 악의를 가진 attacker가 가짜 서버를 구축하여, Push 알림을 아무때나 보낼 수도 있기 때문입니다.

GCP(구글 클라우드 플랫폼)을 사용하고 있는 경우, 조금 더 편리하게 인증이 가능하지만, 일반적인 서버에서도 인증이 가능한 방법을 알아보도록 하겠습니다.

 

Firebase 비공개 키 파일 설정

firebase 프로젝트에 들어가, 설정 버튼을 누른뒤 서비스 계정 탭에서 새 비공개 키 생성 을 클릭하여 비공개키를 다운 받습니다.

 

Spring Boot 프로젝트의, resources/firebase/하위에 서비스 키를 넣습니다.

 

 

의존성 추가

build.gradle파일에 Firebase sdk, okhttp 의존성을 추가합니다.

 

 

AccessToken 발급 받기

FCM이 HTTP v1으로 업데이트 되면서, 기존 API KEY 를 이용하던 것에서 Access Token 을 통한 인증을 하도록 변경이 되었습니다. 따라서 우리는, Firebase로 부터, AccessToken을 가져온뒤, 그것을 Header에 포함하여, Push 알림을 요청할 것입니다.

 

우선, FirebaseCloudMessageService 라는 클래스를 생성하고, getAccessToken() 이라는 메소드를 생성합니다.

 

GoogleCredentials는 GoogleApi를 사용하기 위해서 oauth2를 이용해 인증한 대상을 나타내는 객체입니다. GoogleCredentials의 static메소드인 fromStream()에 앞서 다운받은 firebase_service_key.json 의 inputStream을 넣어주면 인스턴스를 얻을 수 있습니다.

 

https://developers.google.com/identity/protocols/oauth2/scopes#fcm

이때, 인증하는 서버에서 필요로 하는 권한을 지정해주어야 합니다. 이는 다시 반환된 GoogleCredentials 인스턴스의, createScoped를 통해 설정 가능합니다. 원하는 서비스의 scopes는 위의 링크에서 확인 가능합니다.

 

이제 모든 설정을 통해 얻어낸 GoogleCredentials의 객체를 통해서, FCM을 이용할수 있는 권한이 부여된 Oauth2의 AccessToken을 받을 차례입니다. 먼저, refreshIfExpired() 메소드를 호출하여, accessToken을 생성한 뒤, 다시, GoogleCredentials 객체의 getAccessToken() 메소드를 이용해 토큰을 받아온 뒤, getTokenValue()를 이용해 토큰값을 최종적으로 얻어옵니다.

 

이렇게 얻어온 AccessToken은 아래에서, RestAPI를 이용해 FCM에 Push 요청을 보낼때, Header에 설정하여, 인증을 위해 사용할 것입니다.

 

 

 

2. 알림요청 메시지 만들기

https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages/send

이제 알림 요청을 위한 REST API 요청을 만들기전에, FCM에서 Push 알림을 보내기 위해 준수해야하는, Request Body를 만들도록 하겠습니다. FCM에서 수신하는 request body 형식은 위의 링크에서 확인 가능합니다.

 

전체 Request Body 형식

Request Body에 포함될 JSON 형태는 위와 같습니다. 우선 위의 형식을 만족하는 클래스를 만듭니다.

 

만들어질 JSON의 키값이 앞서 살펴본 그림의 키값들과 일치해야 하므로, 각 필드들의 이름을 JSON의 키값과 일치시켜야 합니다. 이제 Message에 포함될 데이터들을 살펴보겠습니다.

 

Message

Message에 포함되는 데이터들은 위의 그림과 같은데요, 너무 많다고 놀라실 필요없습니다. 저희는 꼭 필요한 것만 입력할 것입니다.

 

Message에 포함될 데이터는 위와 같습니다. Notification, token 입니다. Notification의 경우 모든 mobile os를 아우를수 있는 Notification을 제공합니다. token 은, 특정 device에 알림을 보내기위해 사용됩니다.

Push 알림을 수신할 target을 지정하는 필드는, 앞선 그림을 참고하면 token, topic, condition이 존재하는데요, 이들은 무조건 한개만 지정이 가능합니다.

 

Notification

마지막 입니다. 이제 Notification에 담길 데이터를 지정해야합니다. 각각의 설명은 생략하도록 하겠습니다. (문서에 잘나와있거든요)

 

최종적으로 구현된 FCM Request Body 클래스 입니다.

 

이 클래스를 통해 생성된 객체는, Object Mapper에 의해 String으로 변환되어, 아래에서 구현될 Http Post 요청의 Request Body에 포함될 것입니다.

 

 

 

3. FCM에 Push 알림 요청을 위한 HTTP POST Request 만들기

아래에서 자세히 설명드리겠습니다.

 

 

FCM API Endpoint

우리가 요청을 보낼 엔드포인트를 확인할 차례입니다. 우리가 사용할 API는 v1이기 때문에 아래의 URL을 사용합니다.

 

앞선 그림에서 빨간 원 안에 들어갈 Project_Id는 위 그림과 같은 경로에서 찾을 수 있습니다.

 

 

sendMessageTo() 메소드

이 메소드는 매개변수로 전달받은 targetToken에 해당하는 device로 FCM 푸시알림을 전송 요청합니다. tagetToken 의 경우 FCM을 이용해 front를 구현할 때 얻어낼 수 있습니다. 이 포스팅에서는 내용이 길어지므로 우선 생략합니다.

 

Request Body 추가

이제 OkHttp3 를 이용해, Http Post Request를 생성합니다. RequestBody에는 우선, 저희가 앞서 생성한 FcmMessage를 문자열로 변경한 데이터를 넣어주면 되는데요, 이 메시지를 생성하는 makeMessage() 메소드는 아래에서 더 자세히 살펴보겠습니다.

 

header 추가

다음으로는 header에 AccessToken을 추가할 차례입니다. 위와 같이, Authorization을 키로하는 헤더에, Bearer <AccessToken> 형태로 추가해주면 됩니다.

 

https://square.github.io/okhttp/

나머지는 Okhttp 문서를 확인하여 공부하시면 좋을것 같습니다.

 

 

 

makeMessage() 메소드

마지막입니다. FcmMessage를 만들고, 이를 ObjectMapper을 이용해 String으로 변환하여 반환합니다.

 

 


4. 사용법

사용법은 간단합니다. 우리가 지금까지 구현한 FirebaseCloudMessageService 객체를 생성하고, sendMessageTo() 메소드를 호출하면 끝입니다.