콘솔로 이동

iOS 앱에서 메시지 수신

클라이언트 앱이 기기에 설치되면 FCM APN 인터페이스를 통해 메시지를 수신할 수 있습니다. 알림 작성기를 사용해 즉시 사용자 세그먼트로 알림을 전송하거나 애플리케이션 서버에서 APN 인터페이스를 통해 알림 페이로드가 포함된 메시지를 보낼 수 있습니다.

FCM APN 인터페이스를 통해 수신된 메시지를 처리하면 일반적인 사용 사례를 대부분 해결할 수 있습니다. 매우 높은 신뢰성을 요구하는 특수한 사례의 경우 앱에서 직접 FCM 채널 메시지를 처리할 수 있습니다. 업스트림 메시지 전송도 가능합니다.

FCM APN 인터페이스를 통해 수신된 메시지 처리

앱이 백그라운드 상태이면 iOS에서 notification 키가 포함된 메시지를 작업 표시줄로 전달합니다. 알림을 탭하면 앱이 열리고, AppDelegatedidReceiveRemoteNotification 콜백에 알림 내용이 전달됩니다.

다음과 같이 AppDelegate application:didReceiveRemoteNotification:을 구현합니다.

Swift

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)

  completionHandler(UIBackgroundFetchResult.newData)
}

Objective-C

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Print message ID.
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

  // Print full message.
  NSLog(@"%@", userInfo);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Print message ID.
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

  // Print full message.
  NSLog(@"%@", userInfo);

  completionHandler(UIBackgroundFetchResultNewData);
}

앱을 열고 특정 작업을 수행하려면 알림 페이로드에서 click_action을 설정합니다. APN 페이로드의 category 키에 사용할 값을 사용하세요.

알림 메시지 페이로드 해석

알림 메시지의 페이로드는 키와 값으로 구성된 사전입니다. APN을 통해 전송된 알림 메시지는 다음과 같이 APN 페이로드 형식을 따릅니다.

  {
    "aps" : {
      "alert" : {
        "body" : "great match!",
        "title" : "Portugal vs. Denmark",
      },
      "badge" : 1,
    },
    "customKey" : "customValue"
  }

메소드 재구성이 사용 중지된 경우의 메시지 처리

메소드 재구성을 사용 중지한 경우 FCM에서 메시지 전달 및 분석을 추적할 수 있도록 메소드를 호출해야 합니다. 메소드 재구성을 사용 설정하면 이 기능이 자동으로 수행됩니다.

iOS 10 이상에서는 UNUserNotificationCenter delegate를 설정하여 Apple의 디스플레이 알림을 수신하고, FIRMessagingdelegate 속성을 설정하여 FCM의 데이터 메시지를 수신할 수 있습니다. AppDelegate로 이러한 두 대리자를 설정하지 않으면 메시지 처리를 위한 메소드 재구성이 사용 중지됩니다. 메시지 전달 및 분석을 추적하려면 appDidReceiveMessage:를 호출해야 합니다.

Objective-C: iOS 10

// Receive displayed notifications for iOS 10 devices.
// Handle incoming notification messages while app is in the foreground.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  NSDictionary *userInfo = notification.request.content.userInfo;

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

  // Print message ID.
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

  // Print full message.
  NSLog(@"%@", userInfo);

  // Change this to your preferred presentation option
  completionHandler(UNNotificationPresentationOptionNone);
}

// Handle notification messages after display notification is tapped by the user.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void(^)(void))completionHandler {
  NSDictionary *userInfo = response.notification.request.content.userInfo;
  if (userInfo[kGCMMessageIDKey]) {
    NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
  }

  // Print full message.
  NSLog(@"%@", userInfo);

  completionHandler();
}

Objective-C: iOS 9 이하

// With "FirebaseAppDelegateProxyEnabled": NO
   - (void)application:(UIApplication *)application
     didReceiveRemoteNotification:(NSDictionary *)userInfo
           fetchCompletionHandler:
               (void (^)(UIBackgroundFetchResult))completionHandler {
   // Let FCM know about the message for analytics etc.
   [[FIRMessaging messaging] appDidReceiveMessage:userInfo];
   // handle your message.
 }
 

Swift: iOS 10

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {

  // Receive displayed notifications for iOS 10 devices.
  func userNotificationCenter(_ center: UNUserNotificationCenter,
                              willPresent notification: UNNotification,
    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    let userInfo = notification.request.content.userInfo

    // With swizzling disabled you must let Messaging know about the message, for Analytics
    // Messaging.messaging().appDidReceiveMessage(userInfo)

    // Print message ID.
    if let messageID = userInfo[gcmMessageIDKey] {
      print("Message ID: \(messageID)")
    }

    // Print full message.
    print(userInfo)

    // Change this to your preferred presentation option
    completionHandler([])
  }

  func userNotificationCenter(_ center: UNUserNotificationCenter,
                              didReceive response: UNNotificationResponse,
                              withCompletionHandler completionHandler: @escaping () -> Void) {
    let userInfo = response.notification.request.content.userInfo
    // Print message ID.
    if let messageID = userInfo[gcmMessageIDKey] {
      print("Message ID: \(messageID)")
    }

    // Print full message.
    print(userInfo)

    completionHandler()
  }
}

Swift: iOS 9 이하

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
     // Let FCM know about the message for analytics etc.
     FIRMessaging.messaging().appDidReceiveMessage(userInfo)
     // handle your message
   }
 

직접 FCM 채널 메시지 처리

앱이 포그라운드 상태일 때 APN을 우회하여 FCM에서 자동 데이터 전용 메시지를 직접 수신하여 안정성을 높이려면 FCM 서비스에 연결하고 FIRMessagingDelegatemessaging:didReceiveMessage: 메소드로 메시지를 처리해야 합니다. 직접 채널을 사용하도록 설정하면 FCM 백엔드가 안정적인 메시지 대기열을 사용하여 앱이 백그라운드 또는 닫힌 상태일 때 보류 중인 메시지를 추적합니다. 앱이 포그라운드 상태가 되고 연결이 다시 설정되면 클라이언트의 확인을 받을 때까지 채널에서 자동으로 보류 중인 메시지를 클라이언트에게 전송합니다.

연결하려면 AppDelegate에서 shouldEstablishDirectChannel 플래그를 YES로 설정합니다. FCM은 앱이 백그라운드로 전환되면 연결을 종료하고 앱이 포그라운드로 전환되면 다시 연결하는 방식으로 연결을 관리합니다.

또한 AppDelegate에서 useMessagingDelegateForDirectChannel 플래그를 YES로 설정하고 messaging:didReceiveMessage:를 구현합니다. 콜백 유무에 관계없이 앱에서 APN 메시지를 수신할 수 있으나 FCM의 직접 메시지의 경우는 콜백이 필요합니다.

데이터 메시지 페이로드 해석

데이터 메시지의 페이로드는 키와 값으로 구성된 사전입니다. FCM 서버에서 기기로 직접 보낸 데이터 메시지는 아래와 같은 사전 형식으로 표현됩니다.

  {
    "body" : "great match!",
    "title" : "Portugal vs. Denmark",
    "icon" : "myicon"
  }

대기 중인 메시지 및 삭제된 메시지 처리

FCM에 연결하여 데이터 메시지를 수신하는 앱은 FIRMessagingMessagesDeletedNotification을 처리해야 합니다. 특정 기기가 연결될 때 앱에서 대기 중인 메시지가 너무 많거나(100개 초과) 기기가 한 달 이상 FCM에 연결되지 않은 경우 이 콜백이 수신될 수 있습니다. 이 콜백을 수신한 앱 인스턴스는 앱 서버에 전체적으로 동기화를 실시해야 합니다.

앱으로 전달된 메시지의 통계를 파악하려면, 전송되어 iOS 및 Android 기기에서 열린 메시지 수와 Android 앱의 '노출수'(사용자에게 표시된 알림) 데이터가 기록된 FCM 보고 대시보드를 확인합니다.