Receive Messages in an iOS App

Firebase notifications behave differently depending on the foreground/background state of the receiving app. If you want foregrounded apps to receive notification messages or data messages, you’ll need to write code to handle the onMessageReceived callback. For an explanation of the difference between notification and data messages, see Message types.

Handling messages

For devices running iOS 9 and below, implement AppDelegate application:didReceiveRemoteNotification: to handle notifications received when the client app is in the foreground, and all data messages that are sent to the client. The message is a dictionary of keys and values.

Objective-C

// To receive notifications for iOS 9 and below.
- (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

  // Print message ID.
  NSLog(@"Message ID: %@", userInfo[@"gcm.message_id"]);

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

Swift

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

  // Print message ID.
  print("Message ID: \(userInfo["gcm.message_id"]!)")

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

For devices running iOS 10 and above, implement UNUserNotificationCenterDelegate userNotificationCenter:willPresentNotification:withCompletionHandler: to handle notifications received when the client app is in the foreground. The message is a UNNotification object. Implement FIRMessagingDelegate applicationReceivedRemoteMessage: to handle all data messages that are sent to the client. The message is a FIRMessagingRemoteMessage object.

Objective-C

// Receive displayed notifications for iOS 10 devices.
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  // Print message ID.
  NSDictionary *userInfo = notification.request.content.userInfo;
  NSLog(@"Message ID: %@", userInfo[@"gcm.message_id"]);

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

// Receive data message on iOS 10 devices.
- (void)applicationReceivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
  // Print full message
  NSLog(@"%@", [remoteMessage appData]);
}
#endif

Swift

@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
    // Print message ID.
    print("Message ID: \(userInfo["gcm.message_id"]!)")

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

extension AppDelegate : FIRMessagingDelegate {
  // Receive data message on iOS 10 devices.
  func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) {
    print("%@", remoteMessage.appData)
  }
}

Handling messages with method swizzling disabled

If you disable method swizzling, you'll need to call method appDidReceiveMessage:. This lets FCM track message delivery and analytics, which is performed automatically with method swizzling enabled.

Objective-C

// 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

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
  }

Note: since iOS 10, you can set UNUserNotificationCenter delegate to receive display notifications from Apple and FIRMessaging remoteMessageDelegate to receive data messages from FCM. If you do not set these two delegates with AppDelegate, method swizzling for message handling is disabled. You'll need to call method appDidReceiveMessage: to track message delivery and analytics.

Receive and handle messages with notification in the payload

When your app is in the background, iOS directs messages with the notification key to the system tray. A user tap on a notification opens the app, and the content of the notification is passed to the didReceiveRemoteNotification callback if implemented in the AppDelegate.

If you want to open your app and perform a specific action, set click_action in the notification payload. Use the value that you would use for the category key in the APNs payload.

Send feedback about...

Need help? Visit our support page.