본문 바로가기

Android/Firebase

[Firebase] Android12(SDK 31)을 Target할 때 FCM 변경점. (Feat. PendingIntent)

728x90

TargetSDK 31 (Android12)를 대응하는 작업 도중, FCM에서 오류가 발생하여 이를 해결하는 과정을 작성해 두려고 한다.

 

여기서 FCM이란,

Firebase Cloud Messaging의 약자로, Firebase에서 제공해주는 무료 푸시 서비스.

 

라고 생각하면 된다.

 

이번 게시글에서는 푸시 설정을 하는 방법에 대해서는 생략하고,

targetSdk를 31로 설정하였을 때(Android 12), FMC에서 수정되어야 할 사항에 대하여 알아보고자 한다.


우선,

target Sdk Version을 31로 올리고 여러 가지 확인을 하던 와중,

Firebase에서 Push를 테스트하는데 다음과 같은 오류 메시지를 볼 수 있었다.

 

java.lang.IllegalArgumentException: *.*.*.*: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent. Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.

 

(package 명은 * 처리하였다)

 

오류 내용을 확인해보니, Version 31 and above가 너무나도 잘 보인다.

버전 31부터는 PendingIntent를 사용할 때 FLAG_IMMUTABLE이나 FLAG_MUTABLE 설정을 해줘야 한단다.

 

Developer 사이트에 들어가서 확인을 해보니,

Android12를 타깃 하는 경우에, PendingIntent 객체의 변경 가능 여부에 대하여 Flag 설정이 필수로 변경되었다고 한다.

이유는 당연하다시피, 앱의 보안성 강화를 위해서이다.

 

그렇다면,

PendingIntent를 사용하는 부분에 Flag 설정을 해주도록 하자.

 

FCM을 사용하기 위해서 선언했던 FirebaseMessagingService()를 상속받는 Class에서 확인해보자.

 

private fun getPendingIntent(data: String?): PendingIntent {

    ...
    
    return PendingIntent.getActivity(this, 100, intent, PendingIntent.FLAG_IMMUTABLE)
}

 

필자가 사용하는 부분에서는 다음과 같은 메서드를 사용하여 PendingItent에 대한 객체를 가져오고 있었다.

따라서, Flag를 사용하는 부분에 FLAG_IMMUTABLE을 넣어주었다.

오류 내용을 확인해보면, 별 이유 없으면 IMMUTABLE을 사용하길 권장한다고 나와있기 때문이다.

 

헷갈리지 않도록, getActivity는 어떻게 생겼는지 확인해보면

 

public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags) {
    throw new RuntimeException("Stub!");
}

 

와 같이 마지막 인자 값을 flag로 받고 있음을 알 수 있다.

이처럼, PendingIntent가 사용되는 부분을 모두 찾아서 FLAG 값에 FLAG_IMMUTABLE를 넣어주도록 하자.

 

그 후, 빌드를 하고 push를 날려 문제가 해결되었는지 확인해 보자.

 

 

동일한 오류가 뜨면서 정상 동작을 하지 않는다.

 

해당 부분뿐 아니라 추가적으로 변경되어야 하는 부분이 있는 것 같다.

 

구글링을 해보니 module 범위의 gradle dependency를 추가하면 된다고 한다.

나오는 리스트를 하나씩 추가해보도록 하자.

 

implementation 'androidx.work:work-runtime-ktx:2.7.0'

 

해당 값을 추가하고 테스트를 진행해 보았다.

 

결과적으로,

Foreground 상태에서의 Push는 정상적으로 수신이 가능했으나,

Background 상태에서의 Push를 수신했을 때는 위와 동일한 에러가 발생하였다.

 

implementation "com.google.android.gms:play-services-ads:20.6.0"

 

다음은 애드몹 관련한 값으로 보인다.

 

해당 값뿐 아니라, 디펜던시로 추가되어있는 gms 관련한 값들을 최신 버전으로 올려보았으나,

동일하게 오류가 발생하였다.

 

다음으로는, firebase-messaging에 대하여 최신 버전으로 변경하였다.

 

implementation 'com.google.firebase:firebase-messaging:20.0.0'

to

implementation 'com.google.firebase:firebase-messaging:23.0.4'

 

필자가 변경하고 있던 앱에서 사용하던 버전은 20.0.0이었고, 최신 버전은 23.0.4로 상당한 차이를 보이고 있었다.

 

해당 부분을 변경하고 빌드를 실행해보니, 사용되던 함수가 deprecated 되고 새로운 함수를 사용하도록 변경되었다.

 

FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { ... }

 

라는 형태로 사용하고 있었는데, FirebaseInstanceId가 제거되고 FirebaseMessaging으로 변경되었다.

 

FirebaseMessaging.getInstance().token.addOnSuccessListener { ... }

 

따라서 다음과 같이 함수를 수정해주었다.

 

그 후, 빌드하여 다시 한번 Push를 테스트해보니

Background에서도 정상적으로 동작하는 것을 확인할 수 있었다.

 

지금까지 작업한 것들 중 상관이 없는 것이 있을 수 있으므로,

역으로 하나씩 제거하면서 필요하지 않은 부분을 제거해보도록 하였다.

 

 

우선,

FLAG_IMMUTABLE은 targetSDK를 31로 하면 반드시 필요한 부분이기 때문에 제거했을 때 오류가 발생하게 된다.

 

따라서, gradle에 추가한 값들을 확인해 보도록 하였다.

 

implementation 'androidx.work:work-runtime-ktx:2.7.0'

 

해당 참조를 제거해보고 테스트해보았다.

문제없이 정상적으로 동작한다. 따라서 해당 부분은 제거해도 상관없어 보인다.

 

마찬가지로,

 

implementation "com.google.android.gms:play-services-ads:20.6.0"

 

를 제거했을 때도 동일하게 정상 동작하므로, 해당 부분을 제거해도 상관없다.

하지만, 원래 사용하던 부분이라면 최신 버전으로 올린 후에 사용하는 것이 좋을 것으로 보인다.

 

결과적으로,

 

PendingIntent.FLAG_IMMUTABLE

 

해당 Flag 값과,

 

implementation 'com.google.firebase:firebase-messaging:23.0.4'

 

firebase-messaging에 대한 버전을 최신 버전으로 올리는 작업을 통해서 발생했던 문제를 해결할 수 있었다.


버전이 올라감에 따라서 수정이 필요한 부분에서 에러가 발생하여 쉽게 찾아서 해결할 수 있었던 문제였지만,

이번에 Android12를 대응하면서, Dependencies에 추가된 라이브러리들의 버전을 관리해야 한다는 것과 해당 프로젝트의 문제점을 다시 한번 깨닫게 되었다.

 

초기에 프로젝트를 진행할 때 사용한 라이브러리들이 최신화가 되지 않고 그 버전 그대로 사용되고 있는데, 이것이 나중에 많은 문제를 발생시킬 것 같다.

 

현재 해당 라이브러리들을 사용하는데 문제가 없다고 하더라도, target 버전이 올라가게 되면 이전 버전으로는 확실한 대응을 하지 못 할 수 있기 때문에, 짧은 주기는 아니더라도 정기적으로 라이브러리의 버전을 확인하고 업데이트하는 과정이 필요할 것으로 보인다.

 

이번 문제도, 라이브러리의 최신화가 되어있었다면 Flag 값을 추가하는 것만으로도 손쉽게 해결이 가능했을 테니 말이다.

실무를 진행하면서 놓치고 있던 부분이기도 했기 때문에, 이번을 계기로 시간이 될 때 확인을 하여 라이브러리에서 변경된 부분을 확인하고, 업데이트하는 작업도 진행해야겠다.

728x90