Firebase 클라우드 메시징 시작하기


이 빠른 시작에서는 메시지를 안정적으로 보낼 수 있도록 모바일 및 웹 클라이언트 앱에서 Firebase Cloud Messaging을 설정하는 방법을 설명합니다. 서버 환경의 경우 서버 환경 및 FCM을 참고하세요.

Flutter에서 Firebase 클라우드 메시징 클라이언트 앱 설정

타겟팅하는 플랫폼에 따라 추가로 필요한 설정 단계가 있습니다.

iOS+

메서드 재구성

Apple 기기에서 FCM Flutter 플러그인을 사용하려면 메서드 재구성이 필요합니다. 재구성이 없으면 FCM 토큰 처리와 같은 주요 Firebase 기능이 제대로 작동하지 않습니다.

Android

Google Play 서비스

FCM 클라이언트는 Android 4.4 이상의 Google Play 서비스가 설치된 기기 또는 Google API로 Android 4.4를 실행하는 에뮬레이터가 필요합니다. Google Play 스토어를 통해서만 Android 앱을 배포하도록 제한되지는 않습니다.

Play 서비스 SDK를 사용하는 앱은 Google Play 서비스 기능에 액세스하기 전에 항상 기기에 호환되는 Google Play 서비스 APK가 있는지 확인해야 합니다. 기본 활동의 onCreate() 메서드 및 onResume() 메서드 등 두 위치에서 확인 작업을 하는 것이 좋습니다. onCreate()로 확인하면 확인에 성공하지 못한 앱을 사용할 수 없게 됩니다. onResume()으로 확인하면 사용자가 '뒤로' 버튼과 같은 다른 수단을 통해 실행 중인 앱으로 돌아오는 경우에 확인 작업이 계속 수행될 수 있습니다.

기기에 호환되는 Google Play 서비스 버전이 없으면 앱에서 GoogleApiAvailability.makeGooglePlayServicesAvailable()을 호출하여 사용자가 Play 스토어에서 Google Play 서비스를 다운로드하도록 허용할 수 있습니다.

FCM에서 웹 사용자 인증 정보 구성

FCM 웹 인터페이스는 '자발적 애플리케이션 서버 ID' 또는 'VAPID' 키라고 하는 웹 사용자 인증 정보를 사용하여 지원되는 웹 푸시 서비스에 대한 보내기 요청을 승인합니다. 앱에서 푸시 알림을 구독하려면 키 쌍을 Firebase 프로젝트에 연결해야 합니다. Firebase Console을 통해 새 키 쌍을 생성하거나 기존 키 쌍을 가져올 수 있습니다.

FCM 플러그인 설치:

  1. 아직 수행하지 않았으면 Flutter의 Firebase 플러그인을 설치하고 초기화합니다.

  2. Flutter 프로젝트의 루트에서 다음 명령어를 실행하여 플러그인을 설치합니다.

    flutter pub add firebase_messaging
    
  3. 완료되면 Flutter 애플리케이션을 다시 빌드합니다.

    flutter run
    

등록 토큰 액세스

특정 기기로 메시지를 보내려면 기기 등록 토큰을 알아야 합니다. 앱 인스턴스의 등록 토큰을 가져오려면 getToken()을 호출합니다. 알림 권한이 부여되지 않은 경우 이 메서드는 사용자에게 알림 권한을 요청합니다. 그렇지 않은 경우 토큰을 반환하거나 오류가 있으면 예정을 거부합니다.

// You may set the permission requests to "provisional" which allows the user to choose what type
// of notifications they would like to receive once the user receives a notification.
final notificationSettings = await FirebaseMessaging.instance.requestPermission(provisional: true);

// For apple platforms, make sure the APNS token is available before making any FCM plugin API calls
final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
 // APNS token is available, make FCM plugin API requests...
}

웹 플랫폼에서 VAPID 공개 키를 getToken()에 전달합니다.

final fcmToken = await FirebaseMessaging.instance.getToken(vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu");

토큰이 업데이트될 때마다 알림을 받으려면 onTokenRefresh 스트림을 구독합니다.

FirebaseMessaging.instance.onTokenRefresh
    .listen((fcmToken) {
      // TODO: If necessary send token to application server.

      // Note: This callback is fired at each app startup and whenever a new
      // token is generated.
    })
    .onError((err) {
      // Error getting token.
    });

자동 초기화 방지

FCM 등록 토큰이 생성되면 라이브러리는 식별자와 구성 데이터를 Firebase에 업로드합니다. 토큰 자동 생성을 방지하려면 빌드 시간에 자동 초기화를 중지합니다.

iOS

다음과 같이 iOS에서 메타데이터 값을 Info.plist에 추가합니다.

FirebaseMessagingAutoInitEnabled = NO

Android

Android에서는 다음 메타데이터 값을 AndroidManifest.xml에 추가하여 애널리틱스 수집과 FCM 자동 초기화를 중지합니다(둘 다 중지해야 함).

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

런타임 시 FCM 자동 초기화 다시 사용 설정

특정 앱 인스턴스에 auto-init를 사용 설정하려면 setAutoInitEnabled()를 호출합니다.

await FirebaseMessaging.instance.setAutoInitEnabled(true);

이 값을 설정하고 나면 앱을 다시 시작해도 유지됩니다.

테스트 알림 메시지 전송

  1. 대상 기기에 앱을 설치하고 실행합니다. Apple 기기에서는 원격 알림을 수신할 수 있는 권한 요청을 수락해야 합니다.
  2. 앱을 기기에서 백그라운드 상태로 만듭니다.
  3. Firebase Console에서 메시지 페이지를 엽니다.
  4. 첫 번째 메시지인 경우 첫 번째 캠페인 만들기를 선택합니다.
    1. Firebase 알림 메시지를 선택하고 만들기를 선택합니다.
  5. 그렇지 않으면 캠페인 탭에서 새 캠페인을 선택한 후 알림을 선택합니다.
  6. 메시지 본문을 입력합니다.
  7. 오른쪽 창에서 테스트 메시지 전송을 선택합니다.
  8. FCM 등록 토큰 추가 필드에 등록 토큰을 입력합니다.
  9. 테스트를 선택합니다.

테스트를 선택하면 타겟팅된 클라이언트 기기(앱은 백그라운드 상태임)에서 알림을 수신합니다.

앱으로 전송된 메시지의 통계를 파악하려면 Apple 및 Android 기기에서 열린 전송 메시지 수와 Android 앱의 노출 데이터가 기록된 FCM 보고 대시보드를 확인합니다.

상호작용 처리

사용자가 알림을 탭하면 Android 및 iOS의 기본 동작은 애플리케이션을 여는 것입니다. 애플리케이션이 종료된 상태라면 시작되고, 백그라운드에 있다면 포그라운드로 전환됩니다.

알림의 콘텐츠에 따라 애플리케이션이 열릴 때 사용자의 상호작용을 처리하려고 할 수 있습니다. 예를 들어 새 채팅 메시지가 알림을 통해 전송되고 사용자가 이를 선택하면 애플리케이션이 열릴 때 특정 대화를 열려고 할 수 있습니다.

firebase-messaging 패키지는 이 상호작용을 처리하는 두 가지 방법을 제공합니다.

  1. getInitialMessage():: 애플리케이션이 종료된 상태에서 열리면 이 메서드는 RemoteMessage가 포함된 Future를 반환합니다. 소비되면 RemoteMessage가 삭제됩니다.
  2. onMessageOpenedApp: 애플리케이션이 백그라운드 상태에서 열릴 때 RemoteMessage를 게시하는 Stream입니다.

사용자에게 원활한 환경을 보장하려면 두 시나리오를 모두 처리해야 합니다. 다음 코드 예시에서 이를 처리하는 방법을 설명합니다.

class Application extends StatefulWidget {
  @override
  State createState() => _Application();
}

class _Application extends State {
  // In this example, suppose that all messages contain a data field with the key 'type'.
  Future setupInteractedMessage() async {
    // Get any messages which caused the application to open from
    // a terminated state.
    RemoteMessage? initialMessage =
        await FirebaseMessaging.instance.getInitialMessage();

    // If the message also contains a data property with a "type" of "chat",
    // navigate to a chat screen
    if (initialMessage != null) {
      _handleMessage(initialMessage);
    }

    // Also handle any interaction when the app is in the background using a
    // Stream listener
    FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
  }

  void _handleMessage(RemoteMessage message) {
    if (message.data['type'] == 'chat') {
      Navigator.pushNamed(context, '/chat',
        arguments: ChatArguments(message),
      );
    }
  }

  @override
  void initState() {
    super.initState();

    // Run code required to handle interacted messages in an async function
    // as initState() must not be async
    setupInteractedMessage();
  }

  @override
  Widget build(BuildContext context) {
    return Text("...");
  }
}

상호작용을 처리하는 방법은 설정에 따라 다릅니다. 앞서 보여드린 예시는 StatefulWidget을 사용하는 기본 예시입니다.

다음 단계

설정 단계를 완료한 후 다음과 같은 방법으로 Flutter용 FCM을 본격적으로 사용해 보세요.