Firebase Cloud Messaging (FCM) is the new version of GCM. It inherits the reliable and scalable GCM infrastructure, plus new features! See the FAQ to learn more. If you are integrating messaging in a new app, start with FCM. GCM users are strongly recommended to upgrade to FCM, in order to benefit from new FCM features today and in the future. Before you go, please visit our GCM and FCM developer survey to give us feedback!

Migrate a GCM Client App for iOS to Firebase Cloud Messaging

Migrate an existing GCM client app on iOS to Firebase Cloud Messaging (FCM) using the instructions in this guide.

Enabling/disabling method swizzling

Method swizzling available with FCM simplifies your client code. However, for developers who prefer not to use it, FCM allows you to disable method swizzling by adding the FirebaseAppDelegateProxyEnabledflag in the app’s Info.plist file and setting its value to NO (boolean value).

FCM swizzling affects how you handle the default registration token, and how you handle downstream message callbacks. Where applicable, this guide provides migration examples both with and without method swizzling enabled.

Import your GCM project as a Firebase project

  1. In the Firebase console, select Import Google Project.

  2. Select your GCM project from the list of existing projects and select Add Firebase.

  3. In the Firebase welcome screen, select Add Firebase to your iOS App.

  4. Provide your bundle name and optional App store ID, and select Add App. A new GoogleServices-info.plist file for your Firebase app is downloaded.

  5. Select Continue and follow the detailed instructions for creating an xcworkspace file for your app and connecting to Firebase on startup.

Prerequisites

Make sure your valid APNs certificates are uploaded to the Firebase console.

  1. Select the gear icon next to your project name at top left, and select Project Settings.
  2. Select the Cloud Messaging tab.
  3. Select the Upload Certificate button for your develpment certificate, your production certificate, or both. At least one is required.
  4. For each certificate, select the .p12 file, provide the password if any, and select Save.

Switch to FCM in your Podfile

Before
Google/CloudMessaging
After
Firebase/Messaging

Initializing the service

Previously, the GCM API required client apps to start and configure the GCM service. FCM is initialized as part of overall Firebase app initialization.

Before
[[GGLInstanceID sharedInstance] startWithConfig:[GGLInstanceIDConfig defaultConfig]]
[GCMService sharedInstance] startWithConfig:[GCMConfig defaultConfig]];
After
// No extra messaging code required.
// Configure FCM and other Firebase APIs with a single call.
[FIRApp configure];

Default registration token

You must follow different steps to migrate registration token-related code depending on whether or not you disable swizzling. By default, FCM swizzles the AppDelegate methods to:

  • get the APNs token and associate it with the registration token automatically. The FCM SDK swizzles the AppDelegate’s remote notification handlers to get the APNs token for the device.

  • automatically report notification related analytics, such "notification opened" and "notifcation foregrounded." These analytics are available if the message is sent from Firebase Notifications.

Generating the token with swizzling enabled

Before
NSDictionary *instanceIDOptions = @{
    kGGLInstanceIDRegisterAPNSOption : appDelegate.apnsDeviceToken,
    kGGLInstanceIDAPNSServerTypeSandboxOption : @([self isSandboxApp]),
};
[[GGLInstanceID sharedInstance]
    tokenWithAuthorizedEntity:[AppDelegate appGCMSenderID]
                        scope:kGGLInstanceIDScopeGCM
                      options:instanceIDOptions
                      handler:^(NSString *token, NSError *error){
    // handle token or error.
}];
After
// Get the default token
// The first time you call this, the token may not be available, in which case
// the SDK returns nil.
// Once the token is fetched from the server, the SDK posts a token refresh
// notification that you can listen for in order to access the new token.

NSString *token = [[FIRInstanceID instanceID] token];

Generating the token with swizzling disabled

Before
NSDictionary *instanceIDOptions = @{
    kGGLInstanceIDRegisterAPNSOption : appDelegate.apnsDeviceToken,
    kGGLInstanceIDAPNSServerTypeSandboxOption : @([self isSandboxApp]),
};
[[GGLInstanceID sharedInstance]
    tokenWithAuthorizedEntity:[AppDelegate appGCMSenderID]
                        scope:kGGLInstanceIDScopeGCM
                      options:instanceIDOptions
                      handler:^(NSString *token, NSError *error){
    // handle token or error.
}];
After
// With "FirebaseAppDelegateProxyEnabled": NO

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [FIRInstanceID instanceID] setAPNSToken:deviceToken
                                     type:FIRInstanceIDAPNSTokenTypeProd];
}

Token Refresh

FCM does not require the GGLInstanceIDDelegate protocol for token refresh. Instead, the SDK posts the notification kFIRInstanceIDTokenRefreshNotification to let the app know when the token is refreshed. The token refresh notification is invoked whenever the SDK generates a token, including the first time.

Before
@implementation AppDelegate : NSObject 
GGLInstanceIDConfig *config = [GGLInstanceIDConfig defaultConfig];
config.delegate = self;
[[GGLInstanceID sharedInstance] startWithConfig:config];

//#pragma - GGLInstanceIDDelegate protocol
- (void)onTokenRefresh() {
  // get all new tokens, resubscribe to topics etc.
}
@end
After
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    ...

      // Add observer to listen for the token refresh notification.
      [[NSNotificationCenter defaultCenter]
       addObserver:self selector:@selector(onTokenRefresh)
              name:kFIRInstanceIDTokenRefreshNotification object:nil];

            ...

          }

- (void)onTokenRefresh {
  // Get the default token if the earlier default token was nil. If the we already
  // had a default token most likely this will be nil too. But that is OK we just
  // wait for another notification of this type.
  NSString *token = [[FIRInstanceID instanceID] token];
  // custom stuff as before.
}

Downstream send callbacks

In FCM, swizzling relieves your client app of the need to call appDidReceiveMessage for message handling. If you disable swizzling, the API closely resembles GCM’s, only with updated FIRMessaging naming.

Handling downstream callbacks with swizzling enabled

Before
- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:
              (void (^)(UIBackgroundFetchResult))completionHandler {
  // Let GCM know about the message for analytics etc.
  [GCMService appDidReceiveMessage:userInfo];
  // handle your message.
}
After
- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:
              (void (^)(UIBackgroundFetchResult))completionHandler {
  // Handle your message. With swizzling enabled, no need to indicate
  // that a message was received.
}

Handling downstream callbacks with swizzling disabled

Before
- (void)application:(UIApplication *)application
    didReceiveRemoteNotification:(NSDictionary *)userInfo
          fetchCompletionHandler:
              (void (^)(UIBackgroundFetchResult))completionHandler {
  // Let GCM know about the message for analytics etc.
  [GCMService appDidReceiveMessage:userInfo];
  // handle your message.
}
After
- (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.
}

Upstream send callbacks

To receive status updates for upstream sends, GCM apps must implement the GCMReceiverDelegate protocol and implement its methods. With FCM, client apps listen for the relevant notifications by adding observers for each of them.

Before
@implementation AppDelegate : NSObject 
GCMConfig *config = [GCMConfig defaultConfig];
config.delegate = self;
[[GCMConfig sharedInstance] startWithConfig:config];

// GCMReceiverDelegate protocol methods

- (void)willSendDataMessageWithID:(NSString *)messageID error:(NSError *)error;
  // check if any error while sending message
}

- (void)didSendDataMessageWithID:(NSString *)messageID {
  // successfully sent upstream message with id ‘messageID`
}

- (void)didDeleteMessagesOnServer {
  // some messages were deleted(TTL expired) on the server, lets’ retrieve them.
}

@end
After
[[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(sendDataMessageFailure:)
            name:FIRMessagingSendErrorNotification object:nil];

[[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(sendDataMessageSuccess:)
            name:FIRMessagingSendSuccessNotification object:nil];

[[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(didDeleteMessagesOnServer)
            name:FIRMessagingMessagesDeletedNotification object:nil];

// contains error info
- (void)sendDataMessageFailure:(NSNotification *)notification {
  NSString *messageID = (NSString *)message.object;
}
- (void)sendDataMessageSuccess:(NSNotification *)notification {
  NSString *messageID = (NSString *)message.object;
  NSDictionary *userInfo = message.userInfo;
}

- (void)didDeleteMessagesOnServer {
}

Update server endpoints

You can update your server code to use new FCM endpoints for sending messages via HTTP and XMPP. Note that the new FCM version of gcm-http.googleapis.com/gcm/ is fcm.googleapis.com/fcm/ (without "http"):

GCM endpoint FCM endpoint
gcm-http.googleapis.com/gcm/ fcm.googleapis.com/fcm/
gcm-xmpp.googleapis.com fcm-xmpp.googleapis.com

Updating these endpoints is not strictly required, as Google will continue to support the existing GCM endpoints.

Send feedback about...

Cloud Messaging
Cloud Messaging