앱 아이콘 배지를 설정해보자!!

Mario Kim
staygelabstechblog
Published in
7 min readJul 18, 2024

Before Start — 앱 아이콘 배지?

앱에 특정한 알림이 있다는 것을 사용자에게 인지시키기 위해 앱 아이콘 오른쪽 상단에 점 또는 숫자를 띄워주는 기능입니다. 일반적으로 카카오톡이나 라인같은 메신저 앱으로 굉장히 익숙하게 접할 수 있습니다.

누군가 나에게 메시지를 보냈을 때 읽지않은 메시지의 수를 알려주고 싶어!!

이런 요구사항에 의해서 앱 아이콘 배지를 설정해주는 방법을 찾아보게 되었습니다. 다양한 방법이 있겠지만 이번에 사용한 방법은 Firebase를 이용한 푸시메시지를 통해서 앱 아이콘 배지를 설정해주는 방법입니다. (물론 서버사이드에서)

어떻게 설정해주어야 할까? Let’s try it out!

거두절미하고 설정부터 확인을 해보겠습니다. 더욱 세세한 설정에 대해서는 아래 공식문서를 참고하길 부탁드립니다.

https://firebase.google.com/docs/reference/admin/node/firebase-admin.messaging

{
data: item.data,
android: {
notification: {
notificationCount: item.badgeCount,
imageUrl: imageUrl,
},
},
apns: {
payload: {
aps: {
contentAvailable: true,
badge: item.badgeCount,
},
},
fcmOptions: {
imageUrl: imageUrl,
},
},
token: item.token,
};

문서와 라이브러리를 참고한 결과 설정 자체는 간단합니다. 이렇게 설정하고 푸시메시지를 보낸 결과는?

ios와 android에서 결과가 다르다?!

네, 물론 생각한대로 동작하지 않았습니다. 정확히는 ios는 생각한대로 아무런 알림이 없는 푸시로 앱 아이콘 배지를 띄워주는 동작이 가능했지만 android는 빈 제목과 빈 내용의 푸시메시지가 도착했습니다. 시행착오 끝에 알아낸 것은 안드로이드에서 빈 알림(일면 silentPush)을 보내기 위해서는 android라는 옵션 자체에 설정이 없어야 한다는 것이었습니다. 하지만 이렇게 되면 count도 보낼 수가 없으므로 빈 알림으로 앱 아이콘 배지를 띄워주는 방법은 사용할 수 없다고 결론을 내렸습니다.

분리할 수 없다면 기존 알림에 같이 실어서 보내보자!!

말그대로 어차피 읽지 않은 메시지의 수를 알려주기 위한 알림이므로 누군가 메시지를 작성했을 때 발생하는 푸시메시지에 해당 count를 실어서 보내기로 했습니다.

{
notification: {
title,
body,
},
data: item.data,
android: {
notification: {
notificationCount: item.badgeCount,
imageUrl: imageUrl,
},
},
apns: {
payload: {
aps: {
'mutable-content': 1,
badge: item.badgeCount,
},
},
fcmOptions: {
imageUrl: imageUrl,
},
},
token: item.token,
};

이번에는 과연 어떤 결과가?

ios와 android에서 결과가 다르다 2 ?!?!

네, 물론 이번에도 생각한대로 동작하지 않았습니다. 정확히는 ios는 생각한대로 동작을 했지만 android는 알림센터에 쌓여있는 푸시메시지 하나하나에 설정된 notificationCount값을 모두 더해서 보여주는 방식으로 동작했습니다. 테스트와 문서로 확인한 결과 notificationCount가 0이거나 설정하지 않으면 1로 동작했습니다.(참고로 ios에서는 0으로 설정할 경우 앱 배지 아이콘을 삭제하게 됩니다. 설정하지 않는다면 아무런 일도 일어나지 않습니다. → 후에 시간을 절약할 수 있게해준 중요한 부분입니다.) 그리고 알림센터에서 해당 알림을 삭제하면 앱 아이콘 배지도 사라졌습니다. 기본 count와 알림센터는 안드로이드의 OS 레벨에서의 설정인지라 수정을 할 방법은 따로 발견하지 못했지만 notificationCount가 설정된 알림들은 하나로 묶어보기로 했습니다.

{
notification: {
title,
body,
},
data: item.data,
android: {
notification: {
tag: item.type,
notificationCount: item.badgeCount,
imageUrl: imageUrl,
},
},
apns: {
payload: {
aps: {
'mutable-content': 1,
badge: item.badgeCount,
threadId: item.type,
},
},
fcmOptions: {
imageUrl: imageUrl,
},
},
token: item.token,
};

위 설정에서 android에 한 가지를 추가해주었습니다. 바로 tag라는 옵션입니다. 이렇게 해서 푸시메시지를 count가 존재하는 알림이(type으로 구분했습니다.) 서로 하나의 알림으로 묶이도록 설정해주었습니다. 결과적으로는 count가 설정되지 않은 다른 type의 알림들은 1로 계산이 되어서 실제로 우리가 원하는 형태로 읽지 않은 메시지의 수를 정확하게 보여줄 수는 없었지만 이것은 추후 고도화의 영역으로 남겨두기로 했습니다. 그렇다면 끝?

ios와 android에서 결과가 다르다 3 ?!?!?!

하지만 이게 끝이 아니었습니다. android를 해결하자 이번에는 ios에서도 해결해야 하는 현상을 발견하게 되었습니다. android와 다르게 알림센터에서 알림을 삭제해도 앱 아이콘 배지가 사라지지 않고 남아있다는 것이었습니다. 그래도 앞에서 android를 테스트하면서 “ios에서는 0으로 설정할 경우 앱 배지 아이콘을 삭제하게 됩니다.” + “아무런 알림이 없는 푸시로 앱 아이콘 배지를 띄워주는 동작이 가능”→ 이것을 알고 있었다는 것이 다행이었습니다. 그렇게 ios의 경우는 읽음처리를 할 때 푸시메시지를 빈 메시지로 보내서 앱 아이콘 배지를 변경해주기로 했습니다.

{
apns: {
payload: {
aps: {
contentAvailable: true,
badge: item.unreadCount,
},
},
},
token: item.token,
};

위처럼 남은 메시지 숫자만 알려줄 수 있는 빈 푸시메시지를 보내는 것을 마지막으로 앱 아이콘 배지의 설정은 고도화를 남겨두고 일단락짓게 되었습니다.

그리고 남은 일들…

그렇다면 남은 고도화는 무엇일까요?

  1. android에서 tag와 같은 역할을 할 것으로 기대했던 ios의 threadId는 실제로 어떤 역할을 하는가에 대한 검증
  2. android에서 푸시메시지를 channel로 분류해서 특정 channel들의 count만 앱 아이콘 배지에 반영하는 방법
  3. android에서 tag를 조금 더 세세하게 나누고(채팅방별로 알림이 묶일 수 있도록) 그를 통해 특정 tag 또는 count가 설정되어있는 가장 마지막 알림의 count를 앱 아이콘 배지에 반영하는 방법

정도가 남아있습니다. 이것의 해결에 대해서는 조만간 찾아올 앱 아이콘 배지를 설정해보자!! 2편에서 다루어보도록 하겠습니다.

--

--