Firebase Summit에서 발표된 모든 내용을 살펴보고 Firebase로 앱을 빠르게 개발하고 안심하고 앱을 실행하는 방법을 알아보세요. 자세히 알아보기

Android 앱에서 메시지 수신

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

Firebase 알림은 수신 앱의 포그라운드/백그라운드 상태에 따라 다르게 작동합니다. 포그라운드 앱이 알림 메시지 또는 데이터 메시지를 수신하도록 하려면 onMessageReceived 콜백을 처리하는 코드를 작성해야 합니다. 알림 메시지와 데이터 메시지의 차이점에 대한 설명은 메시지 유형 을 참조하십시오.

메시지 처리

메시지를 수신하려면 FirebaseMessagingService 를 확장하는 서비스를 사용하십시오. 서비스는 onMessageReceivedonDeletedMessages 콜백을 재정의해야 합니다. 수신 후 20초(Android Marshmallow의 경우 10초) 이내에 모든 메시지를 처리해야 합니다. onMessageReceived 를 호출하기 전에 발생한 OS 지연에 따라 시간 창은 더 짧아질 수 있습니다. 그 이후에는 Android O의 백그라운드 실행 제한 과 같은 다양한 OS 동작으로 인해 작업을 완료하는 데 방해가 될 수 있습니다. 자세한 내용은 메시지 우선 순위 에 대한 개요를 참조하십시오.

onMessageReceived 는 다음을 제외하고 대부분의 메시지 유형에 제공됩니다.

  • 앱이 백그라운드에 있을 때 전달되는 알림 메시지 입니다. 이 경우 알림은 장치의 시스템 트레이로 전달됩니다. 사용자가 알림을 탭하면 기본적으로 앱 시작 관리자가 열립니다.

  • 백그라운드에서 수신될 때 알림 및 데이터 페이로드가 모두 포함된 메시지입니다 . 이 경우 알림은 장치의 시스템 트레이로 전달되고 데이터 페이로드는 런처 활동의 의도 외 추가로 전달됩니다.

요약해서 말하자면:

앱 상태 공고 데이터 둘 다
전경 onMessageReceived onMessageReceived onMessageReceived
배경 시스템 트레이 onMessageReceived 알림: 시스템 트레이
데이터: 의도 외
메시지 유형에 대한 자세한 내용은 알림 및 데이터 메시지 를 참조하십시오.

앱 매니페스트 수정

FirebaseMessagingService 를 사용하려면 앱 매니페스트에 다음을 추가해야 합니다.

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

또한 알림의 모양을 사용자 지정하려면 기본값을 설정하는 것이 좋습니다. 알림 페이로드에 동등한 값이 설정되지 않을 때마다 적용되는 사용자 정의 기본 아이콘 및 사용자 정의 기본 색상을 지정할 수 있습니다.

사용자 정의 기본 아이콘 및 사용자 정의 색상을 설정하려면 application 태그 내에 다음 행을 추가하십시오.

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
     See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
     notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

Android는 사용자 정의 기본 아이콘을 표시합니다.

  • 알림 작성기 에서 보낸 모든 알림 메시지입니다.
  • 알림 페이로드에 아이콘을 명시적으로 설정하지 않은 알림 메시지입니다.

Android는 사용자 정의 기본 색상을 사용합니다.

  • 알림 작성기 에서 보낸 모든 알림 메시지입니다.
  • 알림 페이로드에 색상을 명시적으로 설정하지 않은 알림 메시지입니다.

사용자 지정 기본 아이콘이 설정되지 않고 알림 페이로드에 아이콘이 설정되지 않은 경우 Android는 흰색으로 렌더링된 애플리케이션 아이콘을 표시합니다.

onMessageReceived 재정의

FirebaseMessagingService.onMessageReceived 메서드를 재정의하여 수신된 RemoteMessage 객체를 기반으로 작업을 수행하고 메시지 데이터를 가져올 수 있습니다.

Java

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Kotlin+KTX

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    if (remoteMessage.data.isNotEmpty()) {
        Log.d(TAG, "Message data payload: ${remoteMessage.data}")

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

onDeletedMessages 재정의

경우에 따라 FCM이 메시지를 전달하지 못할 수 있습니다. 이는 연결 시점에 특정 기기의 앱에 대해 너무 많은 메시지(>100)가 보류 중이거나 기기가 한 달 이상 FCM에 연결되지 않은 경우 발생합니다. 이러한 경우 FirebaseMessagingService.onDeletedMessages() 에 대한 콜백을 수신할 수 있습니다. 앱 인스턴스가 이 콜백을 수신하면 앱 서버와 전체 동기화를 수행해야 합니다. 지난 4주 동안 해당 기기의 앱에 메시지를 보내지 않은 경우 FCM은 onDeletedMessages() 를 호출하지 않습니다.

백그라운드 앱에서 알림 메시지 처리

앱이 백그라운드에 있을 때 Android는 알림 메시지를 시스템 트레이로 보냅니다. 사용자가 알림을 탭하면 기본적으로 앱 런처가 열립니다.

여기에는 알림과 데이터 페이로드(및 알림 콘솔에서 보낸 모든 메시지)가 모두 포함된 메시지가 포함됩니다. 이러한 경우 알림은 장치의 시스템 트레이로 전달되고 데이터 페이로드는 런처 활동의 의도 외 추가로 전달됩니다.

앱으로의 메시지 전달에 대한 자세한 내용은 FCM 보고 대시보드 를 참조하십시오. FCM 보고 대시보드 에는 Android 앱의 "노출"(사용자가 본 알림)에 대한 데이터와 함께 Apple 및 Android 장치에서 보내고 열었던 메시지 수를 기록합니다.

백그라운드 제한된 앱(Android P 이상)

FCM은 사용자가 백그라운드 제한 을 설정한 앱에 메시지를 전달하지 않을 수 있습니다(예: 설정 -> 앱 및 알림 -> [앱 이름] -> 배터리). 앱이 백그라운드 제한에서 제거되면 이전과 같이 앱에 새 메시지가 전달됩니다. 메시지 손실 및 기타 백그라운드 제한 영향을 방지하려면 Android vitals 작업에 나열된 나쁜 동작을 피해야 합니다. 이러한 동작으로 인해 Android 기기에서 앱의 백그라운드가 제한됨을 사용자에게 추천할 수 있습니다. 앱은 isBackgroundRestricted() 를 사용하여 백그라운드 제한 여부를 확인할 수 있습니다.

직접 부팅 모드에서 FCM 메시지 수신

기기가 잠금 해제되기 전에도 앱에 FCM 메시지를 보내려는 개발자는 기기가 직접 부팅 모드에 있을 때 Android 앱이 메시지를 수신하도록 설정할 수 있습니다. 예를 들어 앱 사용자가 잠긴 기기에서도 알람 알림을 받도록 할 수 있습니다.

이 사용 사례를 구축할 때 직접 부팅 모드에 대한 일반적인 모범 사례 및 제한 사항을 준수하십시오. 직접 부팅 가능 메시지의 가시성 을 고려하는 것이 특히 중요합니다. 장치에 대한 액세스 권한이 있는 모든 사용자는 사용자 자격 증명을 입력하지 않고도 이러한 메시지를 볼 수 있습니다.

전제 조건

  • 장치는 직접 부팅 모드로 설정되어야 합니다.
  • 기기에 최신 버전의 Google Play 서비스가 설치되어 있어야 합니다(19.0.54 이상).
  • FCM 메시지를 수신하려면 앱에서 FCM SDK( com.google.firebase:firebase-messaging )를 사용해야 합니다.

앱에서 직접 부팅 모드 메시지 처리 활성화

  1. 앱 수준 Gradle 파일에서 FCM 직접 부팅 지원 라이브러리에 대한 종속성을 추가합니다.

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. 앱 매니페스트에 android:directBootAware="true" 속성을 추가하여 앱의 FirebaseMessagingService 가 직접 부팅을 인식하도록 합니다.

    <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false"
        android:directBootAware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

FirebaseMessagingService 가 직접 부팅 모드에서 실행될 수 있는지 확인하는 것이 중요합니다. 다음 요구 사항을 확인하십시오.

  • 서비스는 직접 부팅 모드에서 실행되는 동안 자격 증명 보호 저장소에 액세스하면 안 됩니다.
  • 서비스는 직접 부팅 모드에서 실행되는 동안 직접 부팅 인식으로 표시되지 않은 Activities , BroadcastReceivers 또는 기타 Services 와 같은 구성 요소를 사용하려고 시도해서는 안 됩니다.
  • 서비스에서 사용하는 모든 라이브러리는 직접 부팅 모드에서 실행되는 동안 자격 증명 보호 저장소에 액세스하거나 non-directBootAware 구성 요소를 호출해서는 안 됩니다. 즉, 서비스에서 호출되는 앱이 사용하는 모든 라이브러리는 직접 부팅을 인식해야 하거나 앱이 직접 부팅 모드에서 실행 중인지 확인하고 해당 모드에서 호출하지 않아야 합니다. 예를 들어 Firebase SDK는 직접 부팅과 함께 작동하지만(직접 부팅 모드에서 충돌 없이 앱에 포함될 수 있음) 많은 Firebase API는 직접 부팅 모드에서 호출되는 것을 지원하지 않습니다.
  • 앱이 사용자 지정 Application 을 사용하는 경우 Application 도 직접 부팅을 인식해야 합니다(직접 부팅 모드에서 자격 증명 보호 저장소에 액세스할 수 없음).

직접 부팅 모드에서 장치로 메시지를 보내는 방법에 대한 지침은 직접 부팅이 활성화된 메시지 보내기 를 참조하십시오.

,

Firebase 알림은 수신 앱의 포그라운드/백그라운드 상태에 따라 다르게 작동합니다. 포그라운드 앱이 알림 메시지 또는 데이터 메시지를 수신하도록 하려면 onMessageReceived 콜백을 처리하는 코드를 작성해야 합니다. 알림 메시지와 데이터 메시지의 차이점에 대한 설명은 메시지 유형 을 참조하십시오.

메시지 처리

메시지를 수신하려면 FirebaseMessagingService 를 확장하는 서비스를 사용하십시오. 서비스는 onMessageReceivedonDeletedMessages 콜백을 재정의해야 합니다. 수신 후 20초(Android Marshmallow의 경우 10초) 이내에 모든 메시지를 처리해야 합니다. onMessageReceived 를 호출하기 전에 발생한 OS 지연에 따라 시간 창은 더 짧아질 수 있습니다. 그 이후에는 Android O의 백그라운드 실행 제한 과 같은 다양한 OS 동작으로 인해 작업을 완료하는 데 방해가 될 수 있습니다. 자세한 내용은 메시지 우선 순위 에 대한 개요를 참조하십시오.

onMessageReceived 는 다음을 제외하고 대부분의 메시지 유형에 제공됩니다.

  • 앱이 백그라운드에 있을 때 전달되는 알림 메시지 입니다. 이 경우 알림은 장치의 시스템 트레이로 전달됩니다. 사용자가 알림을 탭하면 기본적으로 앱 시작 관리자가 열립니다.

  • 백그라운드에서 수신될 때 알림 및 데이터 페이로드가 모두 포함된 메시지입니다 . 이 경우 알림은 장치의 시스템 트레이로 전달되고 데이터 페이로드는 런처 활동의 의도 외 추가로 전달됩니다.

요약해서 말하자면:

앱 상태 공고 데이터 둘 다
전경 onMessageReceived onMessageReceived onMessageReceived
배경 시스템 트레이 onMessageReceived 알림: 시스템 트레이
데이터: 의도 외
메시지 유형에 대한 자세한 내용은 알림 및 데이터 메시지 를 참조하십시오.

앱 매니페스트 수정

FirebaseMessagingService 를 사용하려면 앱 매니페스트에 다음을 추가해야 합니다.

<service
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

또한 알림의 모양을 사용자 지정하려면 기본값을 설정하는 것이 좋습니다. 알림 페이로드에 동등한 값이 설정되지 않을 때마다 적용되는 사용자 정의 기본 아이콘 및 사용자 정의 기본 색상을 지정할 수 있습니다.

사용자 정의 기본 아이콘 및 사용자 정의 색상을 설정하려면 application 태그 내에 다음 행을 추가하십시오.

<!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
     See README(https://goo.gl/l4GJaQ) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
<!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
     notification message. See README(https://goo.gl/6BKBk7) for more. -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />

Android는 사용자 정의 기본 아이콘을 표시합니다.

  • 알림 작성기 에서 보낸 모든 알림 메시지입니다.
  • 알림 페이로드에 아이콘을 명시적으로 설정하지 않은 알림 메시지입니다.

Android는 사용자 정의 기본 색상을 사용합니다.

  • 알림 작성기 에서 보낸 모든 알림 메시지입니다.
  • 알림 페이로드에 색상을 명시적으로 설정하지 않은 알림 메시지입니다.

사용자 지정 기본 아이콘이 설정되지 않고 알림 페이로드에 아이콘이 설정되지 않은 경우 Android는 흰색으로 렌더링된 애플리케이션 아이콘을 표시합니다.

onMessageReceived 재정의

FirebaseMessagingService.onMessageReceived 메서드를 재정의하여 수신된 RemoteMessage 객체를 기반으로 작업을 수행하고 메시지 데이터를 가져올 수 있습니다.

Java

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob();
        } else {
            // Handle message within 10 seconds
            handleNow();
        }

    }

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

Kotlin+KTX

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
    Log.d(TAG, "From: ${remoteMessage.from}")

    // Check if message contains a data payload.
    if (remoteMessage.data.isNotEmpty()) {
        Log.d(TAG, "Message data payload: ${remoteMessage.data}")

        if (/* Check if data needs to be processed by long running job */ true) {
            // For long-running tasks (10 seconds or more) use WorkManager.
            scheduleJob()
        } else {
            // Handle message within 10 seconds
            handleNow()
        }
    }

    // Check if message contains a notification payload.
    remoteMessage.notification?.let {
        Log.d(TAG, "Message Notification Body: ${it.body}")
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

onDeletedMessages 재정의

경우에 따라 FCM이 메시지를 전달하지 못할 수 있습니다. 이는 연결 시점에 특정 기기의 앱에 대해 너무 많은 메시지(>100)가 보류 중이거나 기기가 한 달 이상 FCM에 연결되지 않은 경우 발생합니다. 이러한 경우 FirebaseMessagingService.onDeletedMessages() 에 대한 콜백을 수신할 수 있습니다. 앱 인스턴스가 이 콜백을 수신하면 앱 서버와 전체 동기화를 수행해야 합니다. 지난 4주 동안 해당 기기의 앱에 메시지를 보내지 않은 경우 FCM은 onDeletedMessages() 를 호출하지 않습니다.

백그라운드 앱에서 알림 메시지 처리

앱이 백그라운드에 있을 때 Android는 알림 메시지를 시스템 트레이로 보냅니다. 사용자가 알림을 탭하면 기본적으로 앱 런처가 열립니다.

여기에는 알림과 데이터 페이로드(및 알림 콘솔에서 보낸 모든 메시지)가 모두 포함된 메시지가 포함됩니다. 이러한 경우 알림은 장치의 시스템 트레이로 전달되고 데이터 페이로드는 런처 활동의 의도 외 추가로 전달됩니다.

앱으로의 메시지 전달에 대한 자세한 내용은 FCM 보고 대시보드 를 참조하십시오. FCM 보고 대시보드 에는 Android 앱의 "노출"(사용자가 본 알림)에 대한 데이터와 함께 Apple 및 Android 장치에서 보내고 열었던 메시지 수를 기록합니다.

백그라운드 제한된 앱(Android P 이상)

FCM은 사용자가 백그라운드 제한 을 설정한 앱에 메시지를 전달하지 않을 수 있습니다(예: 설정 -> 앱 및 알림 -> [앱 이름] -> 배터리). 앱이 백그라운드 제한에서 제거되면 이전과 같이 앱에 새 메시지가 전달됩니다. 메시지 손실 및 기타 백그라운드 제한 영향을 방지하려면 Android vitals 작업에 나열된 나쁜 동작을 피해야 합니다. 이러한 동작으로 인해 Android 기기에서 앱의 백그라운드가 제한됨을 사용자에게 추천할 수 있습니다. 앱은 isBackgroundRestricted() 를 사용하여 백그라운드 제한 여부를 확인할 수 있습니다.

직접 부팅 모드에서 FCM 메시지 수신

기기가 잠금 해제되기 전에도 앱에 FCM 메시지를 보내려는 개발자는 기기가 직접 부팅 모드에 있을 때 Android 앱이 메시지를 수신하도록 설정할 수 있습니다. 예를 들어 앱 사용자가 잠긴 기기에서도 알람 알림을 받도록 할 수 있습니다.

이 사용 사례를 구축할 때 직접 부팅 모드에 대한 일반적인 모범 사례 및 제한 사항을 준수하십시오. 직접 부팅 가능 메시지의 가시성 을 고려하는 것이 특히 중요합니다. 장치에 대한 액세스 권한이 있는 모든 사용자는 사용자 자격 증명을 입력하지 않고도 이러한 메시지를 볼 수 있습니다.

전제 조건

  • 장치는 직접 부팅 모드로 설정되어야 합니다.
  • 기기에 최신 버전의 Google Play 서비스가 설치되어 있어야 합니다(19.0.54 이상).
  • FCM 메시지를 수신하려면 앱에서 FCM SDK( com.google.firebase:firebase-messaging )를 사용해야 합니다.

앱에서 직접 부팅 모드 메시지 처리 활성화

  1. 앱 수준 Gradle 파일에서 FCM 직접 부팅 지원 라이브러리에 대한 종속성을 추가합니다.

    implementation 'com.google.firebase:firebase-messaging-directboot:20.2.0'
    
  2. 앱 매니페스트에 android:directBootAware="true" 속성을 추가하여 앱의 FirebaseMessagingService 가 직접 부팅을 인식하도록 합니다.

    <service
        android:name=".java.MyFirebaseMessagingService"
        android:exported="false"
        android:directBootAware="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    

FirebaseMessagingService 가 직접 부팅 모드에서 실행될 수 있는지 확인하는 것이 중요합니다. 다음 요구 사항을 확인하십시오.

  • 서비스는 직접 부팅 모드에서 실행되는 동안 자격 증명 보호 저장소에 액세스하면 안 됩니다.
  • 서비스는 직접 부팅 모드에서 실행되는 동안 직접 부팅 인식으로 표시되지 않은 Activities , BroadcastReceivers 또는 기타 Services 와 같은 구성 요소를 사용하려고 시도해서는 안 됩니다.
  • 서비스에서 사용하는 모든 라이브러리는 직접 부팅 모드에서 실행되는 동안 자격 증명 보호 저장소에 액세스하거나 non-directBootAware 구성 요소를 호출해서는 안 됩니다. 즉, 서비스에서 호출되는 앱이 사용하는 모든 라이브러리는 직접 부팅을 인식해야 하거나 앱이 직접 부팅 모드에서 실행 중인지 확인하고 해당 모드에서 호출하지 않아야 합니다. 예를 들어 Firebase SDK는 직접 부팅과 함께 작동하지만(직접 부팅 모드에서 충돌 없이 앱에 포함될 수 있음) 많은 Firebase API는 직접 부팅 모드에서 호출되는 것을 지원하지 않습니다.
  • 앱이 사용자 지정 Application 을 사용하는 경우 Application 도 직접 부팅을 인식해야 합니다(직접 부팅 모드에서 자격 증명 보호 저장소에 액세스할 수 없음).

직접 부팅 모드에서 장치로 메시지를 보내는 방법에 대한 지침은 직접 부팅이 활성화된 메시지 보내기 를 참조하십시오.