지난 포스팅에 이어서 2번째 FCM 포스팅이다.
지난 포스팅에서는 Firebase Console에 있는 FCM 테스트 메시지 전송 기능으로
앱에서 FCM을 수신해보았다.
이번 포스팅에서는 테스트 메시지 전송 기능이 아닌, FCM을 직접 송신해볼 것이다.
API KEY 설정 (OAuth 2.0 AccessToken )
콘솔에서 제공하는 테스트 메시지 전송 기능은 별도의 API KEY 설정 없이 사용할 수 있다.
(실제로 메시지 수신도 잘 된다)
하지만 직접적으로 FCM을 송·수신 하려면 API KEY 설정이 필요하다.
여기서 추가적으로, 기존의 API KEY는 더 이상 사용되지 않는다.
HTTP v1 방식부터는 OAuth 2.0을 사용하여 Access Token을 발급하여 사용해야 한다.
보통은 서버단에서 이루어지는 작업이지만,
Android 스튜디오 환경에서 Access Token을 조회하고 사용해보겠다.
✅ [프로젝트 설정] → [서비스 계정] → [새 비공개 키 생성]
json 파일이 하나 생성된다.
해당 파일을 Android 프로젝트 내 Asset 폴더에 넣어주자.
참고로, 위 파일은 외부에 노출되어서는 안 된다.
보안에 신경쓰기 바란다.
✅ 안드로이드 환경에서 Access Token 조회하는 방법
GoogleCredentials 클래스를 사용하기 위해 build.gradel에 다음 의존성을 추가한다.
implementation("com.google.auth:google-auth-library-oauth2-http:1.19.0")
MainActivity의 onCreate() 메서드 등에 다음 코드를 입력해주자.
CoroutineScope(Dispatchers.IO).launch {
val asset = resources.assets.open("Asset 폴더에 넣은 파일명.json")
val googleCredential = GoogleCredentials.fromStream(asset)
.createScoped(listOf("https://www.googleapis.com/auth/firebase.messaging"))
googleCredential.refresh()
val accessToken = googleCredential.accessToken
Log.d(TAG, "token : $accessToken")
}
로그에 AccessToken{tokenValue=ya2....} 형식으로 출력되었을 것이다.
tokenValue= 뒷 부분만 잘 복사해주자.
Postman을 활용하여 Firebase API 호출
FCM 서비스를 이용하기 위해서 별도의 대단한 방식은 없다.
단지 HTTP 통신으로 FCM API를 호출해주면 그만이다.
그렇기에 Postman 프로그램을 이용하여 FCM을 송신해 보겠다.
✅ Postman 으로 FCM API 호출
● HTTP Method : POST
● API 주소 : https://fcm.googleapis.com/v1/projects/{프로젝트ID}/messages:send
*프로젝트 ID는 콘솔의 [프로젝트 설정] 페이지에서 확인할 수 있다.
● Header에 다음 값 2개 등록
- Content-Type : application/json
- Authorization : Bearer + 띄어쓰기 + 위에서 얻은 Access Token
● Body → raw 선택 후 json 형식의 데이터 페이로드 작성
{
"message": {
"token": "FCM_TOKEN", // 수신할 FCM 토큰
"notification": {
"title": "테스트 제목",
"body": "테스트 내용"
}
}
}
✅ 결과
실제 FCM API를 호출하여 FCM을 송·수신 하는데 성공했다.
다시 한 번 언급하지만, 실전에서는 위 처럼 Access Token을 안드로이드에서 발급 받지는 않는다.
서버쪽에서 Access Token을 관리해야 한다.
기타
✅ 백그라운드 · 포그라운드 상태에서의 FCM 수신
앱의 현재 상태에 따라 FCM이 수신되는 방식이 다르다.
공식 문서에서 설명하는 FCM 기본 송신 형식은,
페이로드 내 Notification 객체에 데이터를 담아서 전송하는 것이다.
{
"message": {
"notification": {
"title": "테스트 제목",
"body": "테스트 내용"
}
}
}
하지만 앱이 종료된 상태(백그라운드)라면 위 방식으로는 정상적으로 동작하지 않는다.
그렇기에 FCM을 송신할 때, Notification 객체가 아닌 Data 객체에 담아서 전송해야 한다.
{
"message": {
"data": {
"title": "테스트 제목",
"body": "테스트 내용"
}
}
}
송신할 때 "notificaton" → "data" 로 객체 이름만 변경해주면 된다.
onMessageReceived() 메서드에서도 데이터 수신 형식을 수정해주자.
// 기존 notification 방식
val title = message.notification?.title
val body = message.notification?.body
// data 방식으로 변경!
val title = message.data["title"]
val body = message.data["body"]
이제 앱이 백그라운드 상태이더라도 데이터를 문제 없이 수신할 수 있다.
✅ FCM 수신 시 Notification Icon 설정
Notification 클래스를 활용하여 알림을 구현한다면,
앱이 종료된 상태에서 FCM을 수신했을 때 Notification의 Icon이 올바르게 표기되지 않는다.
NotificationCompat.Builder.setSmallIcon() 메서드는 앱이 구동 중일 때만 동작하기 때문이다.
그렇기에 Manifest 파일에 다음과 같은 메타 데이터를 추가해줘야 한다.
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/profile_image" />
● 결과
이제 앱이 종료된 상태에서 FCM을 수신해도 Icon이 잘 표시되는 것을 확인할 수 있다.
2차례에 걸친 포스팅으로 FCM을 직접 사용해보았다.
콘솔 세팅 · 서버단에서의 송신 · 클라이언트단에서 수신 등 과정이 복잡할 수 있지만,
각 플랫폼마다 역할을 확실히 분리하고 이해한다면 어렵진 않다.