다음을 통해 공유


Firebase Cloud Messaging을 사용하여 원격 알림

이 연습에서는 Firebase Cloud Messaging을 사용하여 Xamarin.Android 애플리케이션에서 원격 알림(푸시 알림이라고도 함)을 구현하는 방법에 대한 단계별 설명을 제공합니다. FCM(Firebase Cloud Messaging)과의 통신에 필요한 다양한 클래스를 구현하는 방법을 보여 줍니다. FCM에 액세스하기 위해 Android 매니페스트를 구성하는 방법의 예제를 제공하고 Firebase 콘솔을 사용하여 다운스트림 메시징을 보여 줍니다.

FCM 알림 개요

이 연습에서는 FCM 메시징의 필수 사항을 설명하기 위해 FCMClient라는 기본 앱을 만듭니다. Google Play 서비스의 존재에 대한 FCMClient 검사, FCM에서 등록 토큰을 수신하고, Firebase 콘솔에서 보내는 원격 알림을 표시하고, 토픽 메시지를 구독합니다.

앱의 예제 스크린샷

다음 항목 영역을 탐색합니다.

  1. 백그라운드 알림

  2. 토픽 메시지

  3. 포그라운드 알림

이 연습에서는 FCMClient기능을 증분 방식으로 추가하고 디바이스 또는 에뮬레이터에서 실행하여 FCM과 상호 작용하는 방법을 이해합니다. 로깅을 사용하여 FCM 서버와 라이브 앱 트랜잭션을 감시하고 Firebase 콘솔 알림 GUI에 입력한 FCM 메시지에서 알림이 생성되는 방식을 관찰합니다.

요구 사항

Firebase Cloud Messaging에서 보낼 수 있는 다양한 유형의 메시지를 숙지하는 것이 도움이 될 것입니다. 메시지의 페이로드는 클라이언트 앱이 메시지를 수신하고 처리하는 방법을 결정합니다.

이 연습을 진행하려면 먼저 Google의 FCM 서버를 사용하는 데 필요한 자격 증명을 획득해야 합니다. 이 프로세스는 Firebase Cloud Messaging에 설명되어 있습니다. 특히 이 연습에 제시된 예제 코드와 함께 사용할 google-services.json 파일을 다운로드해야 합니다. Firebase 콘솔에서 프로젝트를 아직 만들지 않았거나 google-services.json 파일을 아직 다운로드하지 않은 경우 Firebase Cloud Messaging을 참조하세요.

예제 앱을 실행하려면 Firebase와 호환되는 Android 테스트 디바이스 또는 에뮬레이터가 필요합니다. Firebase Cloud Messaging은 Android 4.0 이상에서 실행되는 클라이언트를 지원하며, 이러한 디바이스에는 Google Play 스토어 앱도 설치되어 있어야 합니다(Google Play 서비스 9.2.1 이상이 필요). 장치에 Google Play 스토어 앱이 아직 설치되어 있지 않은 경우 Google Play 웹 사이트를 방문하여 다운로드하고 설치합니다. 또는 테스트 디바이스 대신 Google Play 서비스가 설치된 Android SDK 에뮬레이터를 사용할 수 있습니다(Android SDK 에뮬레이터를 사용하는 경우 Google Play 스토어를 설치할 필요가 없음).

앱 프로젝트 시작

시작하려면 FCMClient라는 빈 Xamarin.Android 프로젝트를 새로 만듭니다. Xamarin.Android 프로젝트를 만드는 데 익숙하지 않은 경우 Hello, Android를 참조 하세요. 새 앱을 만든 후 다음 단계는 패키지 이름을 설정하고 FCM과의 통신에 사용할 여러 NuGet 패키지를 설치하는 것입니다.

패키지 이름 설정

Firebase Cloud Messaging에서 FCM 사용 앱의 패키지 이름을 지정했습니다. 이 패키지 이름은 API 키와 연결된 애플리케이션 ID도 사용됩니다. 이 패키지 이름을 사용하도록 앱을 구성합니다.

  1. FCMClient 프로젝트의 속성을 엽니다.

  2. Android 매니페스트 페이지에서 패키지 이름을 설정합니다.

다음 예제에서 패키지 이름은 다음과 같이 com.xamarin.fcmexample설정됩니다.

패키지 이름 설정

Android 매니페스트업데이트하는 동안 사용 권한을 사용하도록 설정해야 Internet 검사.

Important

이 패키지 이름이 Firebase 콘솔에 입력된 패키지 이름과 정확히 일치하지 않으면 클라이언트 앱이 FCM에서 등록 토큰을 받을 수 없습니다.

Xamarin Google Play 서비스 기본 패키지 추가

Firebase Cloud Messaging은 Google Play 서비스에 따라 달라지므로 Xamarin Google Play Services - 기본 NuGet 패키지를 Xamarin.Android 프로젝트에 추가해야 합니다. 버전 29.0.0.2 이상이 필요합니다.

  1. Visual Studio에서 참조 > 를 마우스 오른쪽 단추로 클릭하여 NuGet 패키지 관리...를 클릭합니다.

  2. 찾아보기 탭을 클릭하고 Xamarin.GooglePlayServices.Base를 검색 합니다.

  3. FCMClient 프로젝트에 이 패키지를 설치합니다.

    Google Play 서비스 베이스 설치

NuGet을 설치하는 동안 오류가 발생하면 FCMClient 프로젝트를 닫고 다시 열고 NuGet 설치를 다시 시도합니다.

Xamarin.GooglePlayServices.Base를 설치하면 필요한 모든 종속성도 설치됩니다. MainActivity.cs 편집하고 다음 문을 추가합니다.using

using Android.Gms.Common;

이 문을 사용하면 GoogleApiAvailability Xamarin.GooglePlayServices.Base의 클래스를 FCMClient 코드에서 사용할 수 있습니다. GoogleApiAvailability은 Google Play 서비스의 존재에 대한 검사 데 사용됩니다.

Xamarin Firebase 메시징 패키지 추가

FCM 에서 메시지를 받으려면 Xamarin Firebase - 메시징 NuGet 패키지를 앱 프로젝트에 추가해야 합니다. 이 패키지가 없으면 Android 애플리케이션이 FCM 서버에서 메시지를 받을 수 없습니다.

  1. Visual Studio에서 참조 > 를 마우스 오른쪽 단추로 클릭하여 NuGet 패키지 관리...를 클릭합니다.

  2. Xamarin.Firebase.Messaging을 검색합니다.

  3. FCMClient 프로젝트에 이 패키지를 설치합니다.

    Xamarin Firebase 메시징 설치

Xamarin.Firebase.Messaging을 설치하면 필요한 모든 종속성도 설치됩니다.

다음으로, MainActivity.cs 편집하고 다음 using 문을 추가합니다.

using Firebase.Messaging;
using Firebase.Iid;
using Android.Util;

처음 두 문은 Xamarin.Firebase.Messaging NuGet 패키지의 형식을 FCMClient 코드에서 사용할 수 있도록 합니다. Android.Util 은 FMS를 사용하여 트랜잭션을 관찰하는 데 사용할 로깅 기능을 추가합니다.

Google Services JSON 파일 추가

다음 단계는 프로젝트의 루트 디렉터리에 google-services.json 파일을 추가하는 것입니다.

  1. 프로젝트 폴더에 google-services.json 복사합니다.

  2. 앱 프로젝트에 google-services.json 추가합니다(솔루션 탐색기 모든 파일 표시를 클릭하고 google-services.json 마우스 오른쪽 단추로 클릭한 다음 프로젝트에 포함 선택).

  3. 솔루션 탐색기 창에서 google-services.json 선택합니다.

  4. 속성 창에서 빌드 작업을 GoogleServicesJson으로 설정합니다.

    빌드 작업을 GoogleServicesJson으로 설정

    참고 항목

    GoogleServicesJson 빌드 작업이 표시되지 않으면 솔루션을 저장하고 닫은 다음 다시 엽니다.

google-services.json 프로젝트에 추가되고 GoogleServicesJson 빌드 작업이 설정되면 빌드 프로세스는 클라이언트 ID 및 API 키를 추출한 다음 obj/Debug/android/AndroidManifest.xml 있는 병합/생성된 AndroidManifest.xml 이러한 자격 증명을 추가합니다. 이 병합 프로세스는 FCM 서버에 연결하기 위해 필요한 모든 권한 및 기타 FCM 요소를 자동으로 추가합니다.

Google Play 서비스를 확인하고 알림 채널 만들기

Google은 Google Play 서비스 기능에 액세스하기 전에 Android 앱이 Google Play 서비스 APK의 존재 여부를 검사 것을 권장합니다(자세한 내용은 Google Play 서비스 확인 참조).

앱의 UI에 대한 초기 레이아웃이 먼저 만들어집니다. Resources/layout/Main.axml을 편집하고 해당 내용을 다음 XML로 바꿉니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">
    <TextView
        android:text=" "
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/msgText"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:padding="10dp" />
</LinearLayout>

Google TextView Play 서비스가 설치되어 있는지 여부를 나타내는 메시지를 표시하는 데 사용됩니다. 변경 내용을 Main.axml저장합니다.

MainActivity.cs 편집하고 클래스에 다음 인스턴스 변수를 MainActivity 추가합니다.

public class MainActivity : AppCompatActivity
{
    static readonly string TAG = "MainActivity";

    internal static readonly string CHANNEL_ID = "my_notification_channel";
    internal static readonly int NOTIFICATION_ID = 100;

    TextView msgText;

변수 CHANNEL_ID 이며 NOTIFICATION_ID 이 연습의 뒷부분에 추가 MainActivity 될 메서드 CreateNotificationChannel 에 사용됩니다.

다음 예제 OnCreate 에서는 앱이 FCM 서비스를 사용하기 전에 Google Play 서비스를 사용할 수 있는지 확인합니다. MainActivity 클래스에 다음 메서드를 추가합니다.

public bool IsPlayServicesAvailable ()
{
    int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable (this);
    if (resultCode != ConnectionResult.Success)
    {
        if (GoogleApiAvailability.Instance.IsUserResolvableError (resultCode))
            msgText.Text = GoogleApiAvailability.Instance.GetErrorString (resultCode);
        else
        {
            msgText.Text = "This device is not supported";
            Finish ();
        }
        return false;
    }
    else
    {
        msgText.Text = "Google Play Services is available.";
        return true;
    }
}

이 코드는 디바이스를 검사 Google Play 서비스 APK가 설치되어 있는지 확인합니다. 설치되지 않은 경우 사용자에게 Google Play 스토어에서 APK를 다운로드하거나 디바이스의 시스템 설정에서 사용하도록 설정하도록 지시하는 메시지가 표시됩니다 TextBox .

Android 8.0(API 수준 26) 이상에서 실행되는 앱은 알림을 게시하기 위한 알림 채널을 만들어야 합니다. 필요한 경우 알림 채널을 만드는 클래스에 다음 메서드 MainActivity 를 추가합니다.

void CreateNotificationChannel()
{
    if (Build.VERSION.SdkInt < BuildVersionCodes.O)
    {
        // Notification channels are new in API 26 (and not a part of the
        // support library). There is no need to create a notification
        // channel on older versions of Android.
        return;
    }

    var channel = new NotificationChannel(CHANNEL_ID,
                                          "FCM Notifications",
                                          NotificationImportance.Default)
                  {

                      Description = "Firebase Cloud Messages appear in this channel"
                  };

    var notificationManager = (NotificationManager)GetSystemService(Android.Content.Context.NotificationService);
    notificationManager.CreateNotificationChannel(channel);
}

OnCreate 메서드를 다음 코드로 바꿉니다.

protected override void OnCreate (Bundle bundle)
{
    base.OnCreate (bundle);
    SetContentView (Resource.Layout.Main);
    msgText = FindViewById<TextView> (Resource.Id.msgText);

    IsPlayServicesAvailable ();

    CreateNotificationChannel();
}

IsPlayServicesAvailable는 앱이 시작될 때마다 Google Play 서비스 검사 실행되도록 마지막 OnCreate 에 호출됩니다. 이 메서드 CreateNotificationChannel 는 Android 8 이상을 실행하는 디바이스에 대한 알림 채널이 있는지 확인하기 위해 호출됩니다. 앱에 메서드가 있는 OnResume 경우 앱에서도 OnResume 호출 IsPlayServicesAvailable 해야 합니다. 앱을 완전히 다시 빌드하고 실행합니다. 모두 올바르게 구성된 경우 다음 스크린샷과 같은 화면이 표시됩니다.

앱은 Google Play 서비스를 사용할 수 있음을 나타냅니다.

이 결과를 얻지 못하면 Google Play 서비스 APK가 장치에 설치되어 있는지 확인합니다(자세한 내용은 Google Play 서비스 설정 참조). 또한 앞에서 설명한 대로 FCMClient 프로젝트에 Xamarin.Google.Play.Services.Base 패키지를 추가했는지 확인합니다.

인스턴스 ID 수신기 추가

다음 단계는 Firebase 등록 토큰의 생성, 회전 및 업데이트를 처리하도록 확장하는 FirebaseInstanceIdService 서비스를 추가하는 것입니다. FirebaseInstanceIdService FCM이 디바이스에 메시지를 보낼 수 있게 하려면 서비스가 필요합니다. FirebaseInstanceIdService 서비스가 클라이언트 앱에 추가되면 앱은 FCM 메시지를 자동으로 수신하고 앱이 배경이 될 때마다 알림으로 표시합니다.

Android 매니페스트에서 수신기 선언

AndroidManifest.xml 편집하고 섹션에 다음 <receiver> 요소를 삽입합니다<application>.

<receiver
    android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
    android:exported="false" />
<receiver
    android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="${applicationId}" />
    </intent-filter>
</receiver>

이 XML은 다음을 수행합니다.

  • 각 앱 인스턴스에 FirebaseInstanceIdReceiver 대한 고유 식별자를 제공하는 구현을 선언합니다. 또한 이 수신기는 작업을 인증하고 권한을 부여합니다.

  • 서비스를 안전하게 시작하는 데 사용되는 내부 FirebaseInstanceIdInternalReceiver 구현을 선언합니다.

  • 앱 ID는 프로젝트에 추가된 google-services.json 파일에 저장됩니다. Xamarin.Android Firebase 바인딩은 토큰 ${applicationId} 을 앱 ID로 대체합니다. 앱 ID를 제공하기 위해 클라이언트 앱에서 추가 코드가 필요하지 않습니다.

WakefulBroadcastReceiverFirebaseInstanceIdReceiver 이벤트를 수신 FirebaseInstanceId 하고 FirebaseMessaging 파생된 클래스FirebaseInstanceIdService에 전달하는 것입니다.

Firebase 인스턴스 ID 서비스 구현

FCM에 애플리케이션을 등록하는 작업은 사용자가 제공하는 사용자 지정 FirebaseInstanceIdService 서비스에서 처리됩니다. FirebaseInstanceIdService는 다음 단계를 수행합니다.

  1. 인스턴스 ID API를 사용하여 FCM 및 앱 서버에 액세스하도록 클라이언트 앱에 권한을 부여하는 보안 토큰을 생성합니다. 그 대가로 앱은 FCM에서 등록 토큰다시 가져옵니다.

  2. 앱 서버에 필요한 경우 등록 토큰을 앱 서버로 전달합니다.

MyFirebaseIIDService.cs라는 새 파일을 추가하고 템플릿 코드를 다음으로 바꿉다.

using System;
using Android.App;
using Firebase.Iid;
using Android.Util;

namespace FCMClient
{
    [Service]
    [IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
    public class MyFirebaseIIDService : FirebaseInstanceIdService
    {
        const string TAG = "MyFirebaseIIDService";
        public override void OnTokenRefresh()
        {
            var refreshedToken = FirebaseInstanceId.Instance.Token;
            Log.Debug(TAG, "Refreshed token: " + refreshedToken);
            SendRegistrationToServer(refreshedToken);
        }
        void SendRegistrationToServer(string token)
        {
            // Add custom implementation, as needed.
        }
    }
}

이 서비스는 등록 토큰을 처음 만들거나 변경할 때 호출되는 메서드를 구현 OnTokenRefresh 합니다. 실행하면 OnTokenRefresh 속성(FCM에서 비동기적으로 업데이트됨)에서 FirebaseInstanceId.Instance.Token 최신 토큰을 검색합니다. 이 예제에서는 새로 고친 토큰이 출력 창에서 볼 수 있도록 기록됩니다.

var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);

OnTokenRefresh 는 자주 호출되지 않습니다. 다음과 같은 상황에서 토큰을 업데이트하는 데 사용됩니다.

  • 앱이 설치되거나 제거된 경우

  • 사용자가 앱 데이터를 삭제하는 경우

  • 앱이 인스턴스 ID를 지울 때

  • 토큰의 보안이 손상된 경우

Google의 인스턴스 ID 설명서에 따르면 FCM 인스턴스 ID 서비스는 앱이 주기적으로 토큰을 새로 고치도록 요청합니다(일반적으로 6개월마다).

OnTokenRefresh또한 애플리케이션에서 기본 있는 서버 쪽 계정(있는 경우)과 사용자의 등록 토큰을 연결하는 호출 SendRegistrationToAppServer 도 수행합니다.

void SendRegistrationToAppServer (string token)
{
    // Add custom implementation here as needed.
}

이 구현은 앱 서버의 디자인에 따라 달라지므로 이 예제에서는 빈 메서드 본문이 제공됩니다. 앱 서버에 FCM 등록 정보가 필요한 경우 사용자의 FCM 인스턴스 ID 토큰을 앱에서 기본 서버 쪽 계정과 연결하도록 수정 SendRegistrationToAppServer 합니다. (토큰은 클라이언트 앱에 불투명합니다.)

토큰이 앱 서버 SendRegistrationToAppServer 로 전송되면 기본 토큰이 서버로 전송되었는지 여부를 나타내는 부울을 지정해야 합니다. 이 부울이 false SendRegistrationToAppServer 이면 토큰을 앱 서버로 보냅니다. 그렇지 않으면 이전 호출에서 토큰이 이미 앱 서버로 전송되었습니다. 일부 경우(예: 이 FCMClient 예제)에서는 앱 서버에 토큰이 필요하지 않으므로 이 예제에서는 이 메서드가 필요하지 않습니다.

클라이언트 앱 코드 구현

이제 수신기 서비스가 설치되었으므로 이러한 서비스를 활용하기 위해 클라이언트 앱 코드를 작성할 수 있습니다. 다음 섹션에서는 등록 토큰(인스턴스 ID 토큰이라고도 함)을 기록하는 단추가 UI에 추가되고, 알림에서 앱을 시작할 때 정보를 보기 Intent 위해 MainActivity 더 많은 코드가 추가됩니다.

앱 화면에 추가된 로그 토큰 단추

로그 토큰

이 단계에서 추가된 코드는 데모용으로만 사용됩니다. 프로덕션 클라이언트 앱은 등록 토큰을 기록할 필요가 없습니다. Resources/layout/Main.axml을 편집하고 요소 바로 다음에 다음 Button 선언을 TextView 추가합니다.

<Button
  android:id="@+id/logTokenButton"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:text="Log Token" />

MainActivity.OnCreate 메서드의 끝에 다음 코드를 추가합니다.

var logTokenButton = FindViewById<Button>(Resource.Id.logTokenButton);
logTokenButton.Click += delegate {
    Log.Debug(TAG, "InstanceID token: " + FirebaseInstanceId.Instance.Token);
};

이 코드는 로그 토큰 단추를 탭할 때 현재 토큰출력 창에 기록합니다.

알림 의도 처리

사용자가 FCMClient에서 발급된 알림을 탭하면 해당 알림 메시지와 함께 제공되는 모든 데이터를 추가 기능으로 Intent 사용할 수 있습니다. MainActivity.cs 편집하고 메서드 맨 위에 OnCreate 다음 코드를 추가합니다(호출 IsPlayServicesAvailable전).

if (Intent.Extras != null)
{
    foreach (var key in Intent.Extras.KeySet())
    {
        var value = Intent.Extras.GetString(key);
        Log.Debug(TAG, "Key: {0} Value: {1}", key, value);
    }
}

사용자가 알림 메시지를 탭하면 앱의 시작 관리자 Intent 가 실행되므로 이 코드는 출력 창에 Intent 포함된 모든 데이터를 기록합니다. 다른 Intent 항목이 발생 click_action 해야 하는 경우 알림 메시지의 필드를 해당 Intent 필드로 설정해야 합니다(지정되지 않은 click_action 경우 시작 관리자 Intent 가 사용됨).

백그라운드 알림

FCMClient 앱을 빌드하고 실행합니다. 로그 토큰 단추가 표시됩니다.

로그 토큰 단추가 표시됩니다.

로그 토큰 단추를 탭합니다. IDE 출력 창에 다음과 같은 메시지가 표시됩니다.

출력 창에 표시되는 인스턴스 ID 토큰

토큰으로 레이블이 지정된 긴 문자열은 Firebase 콘솔에 붙여넣을 인스턴스 ID 토큰입니다. 이 문자열을 선택하고 클립보드에 복사합니다. 인스턴스 ID 토큰이 표시되지 않으면 메서드 맨 OnCreate 위에 다음 줄을 추가하여 google-services.json 올바르게 구문 분석되었는지 확인합니다.

Log.Debug(TAG, "google app id: " + GetString(Resource.String.google_app_id));

출력 창에 기록된 값은 google_app_id google-services.json 기록된 값과 일치 mobilesdk_app_id 해야 합니다. google-services.json Resource.String.google_app_id 처리할 때 msbuild에서 생성됩니다.

메시지 보내기

Firebase 콘솔에 로그인하고, 프로젝트를 선택하고, 알림을 클릭한 다음, 첫 번째 메시지 보내기를 클릭합니다.

첫 번째 메시지 보내기 단추

메시지 작성 페이지에서 메시지 텍스트를 입력하고 단일 디바이스를 선택합니다. IDE 출력 창에서 인스턴스 ID 토큰을 복사하여 Firebase 콘솔의 FCM 등록 토큰 필드에 붙여넣습니다.

메시지 작성 대화 상자

Android 디바이스(또는 에뮬레이터)에서 Android 개요 단추를 탭하고 홈 화면을 터치하여 앱을 배경화합니다. 디바이스가 준비되면 Firebase 콘솔에서 SEND MESSAGE를 클릭합니다.

메시지 보내기 단추

메시지 검토 대화 상자가 표시되면 SEND를 클릭합니다. 알림 아이콘은 디바이스(또는 에뮬레이터)의 알림 영역에 표시됩니다.

알림 아이콘이 표시됩니다.

알림 아이콘을 열어 메시지를 봅니다. 알림 메시지는 Firebase 콘솔의 메시지 텍스트 필드에 입력된 것과 정확히 일치해야 합니다.

디바이스에 알림 메시지가 표시됩니다.

알림 아이콘을 탭하여 FCMClient 앱을 시작합니다. Intent FCMClient전송된 엑스트라는 IDE 출력 창에 나열됩니다.

키, 메시지 ID 및 축소 키의 의도 추가 목록

이 예제 에서 from 키는 앱의 Firebase 프로젝트 번호(이 예제 41590732에서는)로 설정되고 collapse_key 패키지 이름(com.xamarin.fcmexample)으로 설정됩니다. 메시지를 받지 못한 경우 디바이스(또는 에뮬레이터)에서 FCMClient 앱을 삭제하고 위의 단계를 반복합니다.

참고 항목

앱을 강제로 닫으면 FCM에서 알림 배달을 중지합니다. Android는 백그라운드 서비스 브로드캐스트가 실수로 또는 불필요하게 중지된 애플리케이션의 구성 요소를 시작하는 것을 방지합니다. (이 동작에 대한 자세한 내용은 다음을 참조하세요 .중지된 애플리케이션에서 컨트롤을 시작합니다.) 이러한 이유로 실행할 때마다 수동으로 앱을 제거하고 디버그 세션에서 중지해야 합니다. 이렇게 하면 FCM에서 새 토큰을 생성하여 메시지가 계속 수신되도록 합니다.

사용자 지정 기본 알림 아이콘 추가

이전 예제에서 알림 아이콘은 애플리케이션 아이콘으로 설정됩니다. 다음 XML은 알림에 대한 사용자 지정 기본 아이콘을 구성합니다. Android는 알림 아이콘이 명시적으로 설정되지 않은 모든 알림 메시지에 대해 이 사용자 지정 기본 아이콘을 표시합니다.

사용자 지정 기본 알림 아이콘을 추가하려면 Resources/drawable 디렉터리에 아이콘을 추가하고, AndroidManifest.xml 편집하고, 섹션에 <application> 다음 <meta-data> 요소를 삽입합니다.

<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />

이 예제에서는 Resources/drawable/ic_stat_ic_notification.png 있는 알림 아이콘이 사용자 지정 기본 알림 아이콘으로 사용됩니다. 사용자 지정 기본 아이콘이 AndroidManifest.xml 구성되지 않고 알림 페이로드에 아이콘이 설정되지 않은 경우 Android는 애플리케이션 아이콘을 알림 아이콘으로 사용합니다(위의 알림 아이콘 스크린샷에 표시됨).

토픽 메시지 처리

지금까지 작성된 코드는 등록 토큰을 처리하고 앱에 원격 알림 기능을 추가합니다. 다음 예제에서는 토픽 메시지를 수신 대기하고 사용자에게 원격 알림으로 전달하는 코드를 추가합니다. 토픽 메시지는 특정 토픽을 구독하는 하나 이상의 디바이스로 전송되는 FCM 메시지입니다. 토픽 메시지에 대한 자세한 내용은 토픽 메시징을 참조 하세요.

토픽 구독

Resources/layout/Main.axml을 편집하고 이전 Button 요소 바로 다음에 다음 Button 선언을 추가합니다.

<Button
  android:id="@+id/subscribeButton"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:layout_marginTop="20dp"
  android:text="Subscribe to Notifications" />

이 XML은 레이아웃에 알림 구독 단추를 추가합니다. MainActivity.cs 편집하고 메서드 끝에 OnCreate 다음 코드를 추가합니다.

var subscribeButton = FindViewById<Button>(Resource.Id.subscribeButton);
subscribeButton.Click += delegate {
    FirebaseMessaging.Instance.SubscribeToTopic("news");
    Log.Debug(TAG, "Subscribed to remote notifications");
};

이 코드는 레이아웃에서 알림 구독 단추를 찾고 구독된 토픽, 뉴스를 전달하여 호출FirebaseMessaging.Instance.SubscribeToTopic하는 코드에 해당 클릭 처리기를 할당합니다. 사용자가 구독 단추를 탭하면 앱이 뉴스 항목을 구독합니다. 다음 섹션에서 는 Firebase 콘솔 알림 GUI에서 뉴스 토픽 메시지를 보냅니다.

토픽 메시지 보내기

앱을 제거하고 다시 빌드한 다음 다시 실행합니다. 알림 구독 단추를 클릭합니다.

알림 구독 단추

앱이 성공적으로 구독된 경우 IDE 출력 창에 항목 동기화가 성공했음을 확인할 수 있습니다.

출력 창에 토픽 동기화 성공 메시지가 표시됩니다.

다음 단계를 사용하여 토픽 메시지를 보냅니다.

  1. Firebase 콘솔에서 새 메시지를 클릭합니다.

  2. 메시지 작성 페이지에서 메시지 텍스트를 입력하고 토픽을 선택합니다.

  3. 토픽 풀다운 메뉴에서 기본 제공 토픽, 뉴스를 선택합니다.

    뉴스 항목 선택

  4. Android 디바이스(또는 에뮬레이터)에서 Android 개요 단추를 탭하고 홈 화면을 터치하여 앱을 배경화합니다.

  5. 디바이스가 준비되면 Firebase 콘솔에서 SEND MESSAGE를 클릭합니다.

  6. IDE 출력 창을 확인하여 로그 출력에서 /topics/news를 확인합니다.

    /topic/news의 메시지가 표시됩니다.

이 메시지가 출력 창에 표시되면 Android 디바이스의 알림 영역에도 알림 아이콘이 표시됩니다. 알림 아이콘을 열어 토픽 메시지를 봅니다.

토픽 메시지가 알림으로 표시됨

메시지를 받지 못한 경우 디바이스(또는 에뮬레이터)에서 FCMClient 앱을 삭제하고 위의 단계를 반복합니다.

포그라운드 알림

포그라운드된 앱에서 알림을 받으려면 .FirebaseMessagingService 이 서비스는 데이터 페이로드를 수신하고 업스트림 메시지를 보내는 데에도 필요합니다. 다음 예제에서는 확장하는 FirebaseMessagingService 서비스를 구현하는 방법을 보여 줍니다. 결과 앱은 포그라운드에서 실행되는 동안 원격 알림을 처리할 수 있습니다.

FirebaseMessagingService 구현

서비스는 FirebaseMessagingService Firebase에서 메시지를 받고 처리하는 역할을 담당합니다. 각 앱은 이 형식을 서브클래스하고 들어오는 메시지를 처리하도록 재정의 OnMessageReceived 해야 합니다. 앱이 포그라운드에 있는 경우 콜백은 OnMessageReceived 항상 메시지를 처리합니다.

참고 항목

앱은 들어오는 Firebase 클라우드 메시지를 처리하는 데 10초밖에 없습니다. 이보다 오래 걸리는 모든 작업은 Android 작업 스케줄러 또는 Firebase 작업 디스패처와 같은 라이브러리를 사용하여 백그라운드 실행을 예약해야 합니다.

MyFirebaseMessagingService.cs 이라는 새 파일을 추가하고 템플릿 코드를 다음으로 바꿉다.

using System;
using Android.App;
using Android.Content;
using Android.Media;
using Android.Util;
using Firebase.Messaging;

namespace FCMClient
{
    [Service]
    [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
    public class MyFirebaseMessagingService : FirebaseMessagingService
    {
        const string TAG = "MyFirebaseMsgService";
        public override void OnMessageReceived(RemoteMessage message)
        {
            Log.Debug(TAG, "From: " + message.From);
            Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
        }
    }
}

MESSAGING_EVENT 새 FCM 메시지가 다음으로 전달MyFirebaseMessagingService되도록 의도 필터를 선언해야 합니다.

[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]

클라이언트 앱이 FCM OnMessageReceived 에서 메시지를 받으면 해당 메서드를 호출하여 전달된 개체에서 RemoteMessage 메시지 콘텐츠를 추출합니다 GetNotification . 다음으로 IDE 출력 창에서 볼 수 있도록 메시지 콘텐츠를 기록합니다.

var body = message.GetNotification().Body;
Log.Debug(TAG, "Notification Message Body: " + body);

참고 항목

중단점을 설정하는 경우 FCM에서 FirebaseMessagingService메시지를 전달하는 방법 때문에 디버깅 세션이 이러한 중단점에 도달할 수도 있고 그렇지 않을 수도 있습니다.

다른 메시지 보내기

앱을 제거하고, 다시 빌드하고, 다시 실행하고, 다음 단계에 따라 다른 메시지를 보냅니다.

  1. Firebase 콘솔에서 새 메시지를 클릭합니다.

  2. 메시지 작성 페이지에서 메시지 텍스트를 입력하고 단일 디바이스를 선택합니다.

  3. IDE 출력 창에서 토큰 문자열을 복사하여 이전과 같이 Firebase 콘솔의 FCM 등록 토큰 필드에 붙여넣습니다.

  4. 앱이 포그라운드에서 실행되고 있는지 확인하고 Firebase 콘솔에서 SEND MESSAGE를 클릭합니다.

    콘솔에서 다른 메시지 보내기

  5. 메시지 검토 대화 상자가 표시되면 SEND를 클릭합니다.

  6. 들어오는 메시지가 IDE 출력 창에 기록됩니다.

    출력 창에 인쇄된 메시지 본문

로컬 알림 보낸 사람 추가

이 재기본 예제에서는 들어오는 FCM 메시지가 앱이 포그라운드에서 실행되는 동안 시작되는 로컬 알림으로 변환됩니다. MyFirebaseMessageService.cs 편집하고 다음 using 문을 추가합니다.

using FCMClient;
using System.Collections.Generic;

MyFirebaseMessagingService에 다음 메서드를 추가합니다.

void SendNotification(string messageBody, IDictionary<string, string> data)
{
    var intent = new Intent(this, typeof(MainActivity));
    intent.AddFlags(ActivityFlags.ClearTop);
    foreach (var key in data.Keys)
    {
        intent.PutExtra(key, data[key]);
    }

    var pendingIntent = PendingIntent.GetActivity(this,
                                                  MainActivity.NOTIFICATION_ID,
                                                  intent,
                                                  PendingIntentFlags.OneShot);

    var notificationBuilder = new  NotificationCompat.Builder(this, MainActivity.CHANNEL_ID)
                              .SetSmallIcon(Resource.Drawable.ic_stat_ic_notification)
                              .SetContentTitle("FCM Message")
                              .SetContentText(messageBody)
                              .SetAutoCancel(true)
                              .SetContentIntent(pendingIntent);

    var notificationManager = NotificationManagerCompat.From(this);
    notificationManager.Notify(MainActivity.NOTIFICATION_ID, notificationBuilder.Build());
}

이 알림을 백그라운드 알림과 구분하기 위해 이 코드는 애플리케이션 아이콘과 다른 아이콘으로 알림을 표시합니다. 파일 ic_stat_ic_notification.png Resources/drawable에 추가하고 FCMClient 프로젝트에 포함합니다.

이 메서드는 SendNotification 알림을 만드는 데 사용 NotificationCompat.Builder 되며 NotificationManagerCompat 알림을 시작하는 데 사용됩니다. 알림에는 사용자가 앱을 열고 전달된 messageBody문자열의 내용을 볼 수 있는 알림이 있습니다PendingIntent. 자세한 NotificationCompat.Builder내용은 로컬 알림을 참조 하세요.

메서드의 SendNotification 끝에서 메서드를 호출합니다.OnMessageReceived

public override void OnMessageReceived(RemoteMessage message)
{
    Log.Debug(TAG, "From: " + message.From);

    var body = message.GetNotification().Body;
    Log.Debug(TAG, "Notification Message Body: " + body);
    SendNotification(body, message.Data);
}

이러한 변경으로 SendNotification 인해 앱이 포그라운드에 있는 동안 알림이 수신될 때마다 실행되고 알림 영역이 표시됩니다.

앱이 백그라운드 에 있는 경우 메시지의 페이로드에 따라 메시지가 처리되는 방법이 결정됩니다.

  • 알림 – 메시지가 시스템 트레이전송됩니다. 로컬 알림이 표시됩니다. 사용자가 알림을 탭하면 앱이 시작됩니다.
  • 데이터 – 메시지가 .에 의해 OnMessageReceived처리됩니다.
  • 둘 다 - 알림 및 데이터 페이로드가 모두 있는 메시지는 시스템 트레이로 전달됩니다. 앱이 시작되면 데이터 페이로드가 앱을 시작하는 데 사용된 페이로드에 표시됩니다 ExtrasIntent .

이 예제에서는 앱이 백그라운드로 설정되면 SendNotification 메시지에 데이터 페이로드가 있는 경우 실행됩니다. 그렇지 않으면 백그라운드 알림(이 연습의 앞부분에서 설명)이 시작됩니다.

마지막 메시지 보내기

앱을 제거하고, 다시 빌드하고, 다시 실행한 다음, 다음 단계를 사용하여 마지막 메시지를 보냅니다.

  1. Firebase 콘솔에서 새 메시지를 클릭합니다.

  2. 메시지 작성 페이지에서 메시지 텍스트를 입력하고 단일 디바이스를 선택합니다.

  3. IDE 출력 창에서 토큰 문자열을 복사하여 이전과 같이 Firebase 콘솔의 FCM 등록 토큰 필드에 붙여넣습니다.

  4. 앱이 포그라운드에서 실행되고 있는지 확인하고 Firebase 콘솔에서 SEND MESSAGE를 클릭합니다.

    포그라운드 메시지 보내기

이번에는 출력 창에 기록된 메시지도 새 알림에 패키지됩니다. 앱이 포그라운드에서 실행되는 동안 알림 트레이에 알림 아이콘이 표시됩니다.

포그라운드 메시지의 알림 아이콘

알림을 열면 Firebase 콘솔 알림 GUI에서 보낸 마지막 메시지가 표시됩니다.

포그라운드 아이콘이 표시된 포그라운드 알림

FCM에서 연결 끊기

토픽에서 구독을 취소하려면 FirebaseMessaging 클래스에서 UnsubscribeFromTopic 메서드를 호출합니다. 예를 들어 이전에 구독한 뉴스 토픽에서 구독을 취소하려면 다음 처리기 코드를 사용하여 구독 취소 단추를 레이아웃에 추가할 수 있습니다.

var unSubscribeButton = FindViewById<Button>(Resource.Id.unsubscribeButton);
unSubscribeButton.Click += delegate {
    FirebaseMessaging.Instance.UnsubscribeFromTopic("news");
    Log.Debug(TAG, "Unsubscribed from remote notifications");
};

FCM에서 디바이스의 등록을 모두 취소하려면 FirebaseInstanceId 클래스에서 DeleteInstanceId 메서드를 호출하여 인스턴스 ID를 삭제합니다. 예시:

FirebaseInstanceId.Instance.DeleteInstanceId();

이 메서드 호출은 인스턴스 ID와 연결된 데이터를 삭제합니다. 따라서 디바이스에 FCM 데이터를 정기적으로 보내는 작업이 중단됩니다.

문제 해결

다음은 Xamarin.Android에서 Firebase Cloud Messaging을 사용할 때 발생할 수 있는 문제 및 해결 방법을 설명합니다.

FirebaseApp이 초기화되지 않음

경우에 따라 다음 오류 메시지가 표시 될 수 있습니다.

Java.Lang.IllegalStateException: Default FirebaseApp is not initialized in this process
Make sure to call FirebaseApp.initializeApp(Context) first.

이는 솔루션을 클린 프로젝트를 다시 빌드하여 해결할 수 있는 알려진 문제입니다(클린 솔루션 빌드>, 솔루션 다시 빌드>).

요약

이 연습에서는 Xamarin.Android 애플리케이션에서 Firebase Cloud Messaging 원격 알림을 구현하는 단계를 자세히 설명했습니다. FCM 통신에 필요한 패키지를 설치하는 방법을 설명하고 FCM 서버에 액세스하기 위해 Android 매니페스트를 구성하는 방법을 설명했습니다. Google Play 서비스의 존재에 대해 검사 방법을 보여 주는 예제 코드를 제공했습니다. 등록 토큰을 위해 FCM과 협상하는 인스턴스 ID 수신기 서비스를 구현하는 방법을 설명했으며, 앱이 백그라운드로 설정된 동안 이 코드가 백그라운드 알림을 만드는 방법을 설명했습니다. 토픽 메시지를 구독하는 방법을 설명했으며, 앱이 포그라운드에서 실행되는 동안 원격 알림을 수신하고 표시하는 데 사용되는 메시지 수신기 서비스의 예제 구현을 제공했습니다.