Android
[안드로이드]FCM 에서 PendingIntent가 재사용되는 문제와 해결 방법
dada123
2025. 4. 21. 22:08
반응형
FCM 관련 기능을 개발 중 서버에서 전달받은 RemoteMessage값이 변경되지 않는 문제가 발생하여 소스를 수정을 하게되었다.
이 현상은 앱에서 Firebase Cloud Messaging(FCM)을 통해 푸시 알림을 수신하고, 알림을 탭했을 때 특정 데이터를 액티비티로 전달하는 기능을 구현하다 보면, 발생하는 문제이다.
1. 문제 상황
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
);
이렇게 만들었더니, 푸시 알림을 여러 번 받아도 처음 받은 메시지의 데이터만 전달되고, 그 이후 알림은 클릭해도 이전 데이터가 유지되는 현상이 발생하였다.
❓ 왜 이런 일이 발생할까?
2. 원인: PendingIntent는 내부적으로 캐싱되어 재사용됨
Android의 PendingIntent는 requestCode, Intent 내용, flags 등을 기준으로 같은 게 있으면 재사용한다.
즉, 새로운 알림을 클릭해도 이전 알림 클릭 시의 Intent가 그대로 재사용되며, Intent의 extras도 덮어쓰기되지 않음!
3. 해결 방법: Intent 또는 requestCode를 고유하게 만들어라!
방법 1) Intent에 고유 action 설정
intent.setAction("ACTION_" + System.currentTimeMillis());
방법 2) 고유한 requestCode 사용
int requestCode = (int) System.currentTimeMillis();
해결 방법은 Intent에 고유 action을 추가하거나, 고유한 requestCode를 사용하면 된다고 한다. 나는 첫번째 방법을 통해 pendingIntent의 캐싱을 방지하였다. 이렇게 하면 PendingIntent.getActivity()가 동일하지 않다고 판단하고, 매번 새롭게 만들어진 Intent를 사용된다.
4. 예시) FCM 알림 클릭 시 최신 데이터 전달
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
String sessionId = remoteMessage.getData().get("sessionId");
Intent intent = new Intent(this, IntroActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("sessionId", sessionId);
// 고유 action을 부여해 PendingIntent 재사용 방지
intent.setAction("ACTION_" + System.currentTimeMillis());
// requestCode도 고유하게 설정
int requestCode = (int) System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
requestCode,
intent,
PendingIntent.FLAG_IMMUTABLE
);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default_channel_id")
.setSmallIcon(R.drawable.noti)
.setContentTitle("새로운 알림")
.setContentText("알림 클릭 시 최신 데이터가 전달.")
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(requestCode, builder.build()); // notify ID도 다르게 설정하면 여러 알림 표시 가능
}
5. 결론
문제 | 원인 | 해결책 |
---|---|---|
FCM 알림 클릭 시 항상 이전 데이터만 전달됨 | PendingIntent가 내부적으로 재사용됨 | Intent에 고유한 action 부여 또는 requestCode를 고유하게 설정 |
6. 마무리
- PendingIntent.FLAG_UPDATE_CURRENT를 사용하면 일부 extras는 덮어써지지만, 확실하지 않으니 고유한 Intent를 만드는 것이 가장 안전하다.
- 알림을 여러 개 표시하고 싶다면 notify(id, builder.build())에서 id도 고유하게 설정한다
반응형