Implementing Firebase Cloud Messaging (FCM) into your iOS App

One problem with any mobile project which using push notification, is developers must handle both Google Cloud Messaging for Android and Apple Push Notification for iOS at their back-end. Using third-party solutions like Firebase Cloud Messaging (FCM) simplifies this process by making push notification work -as-a-service seamlessly between both Android and iOS. Especially with Android as FCM is going to officially replaced GCM soon. Today, I want to help you to quickly setup Firebase Cloud Messaging iOS by using Swift with CocoaPods.

Prerequisites

First, you should go to Firebase dashboard, create a project, or add iOS app to your existing project by follow Firebase introduction.

FCM_iOS_Add_App

Enter your app bundle ID and get the GoogleService-Info.plist file. Drag this file to your XCode project.
FCM_iOS_Bundle_ID

FCM_iOS_PList_File

Setup CocoaPods

If your project have not used CocoaPods yet, then open Terminal and navigate to your project directory, then type the following command:

$ pod init

Edit Podfile and add Firebase pods, note that you can have two options: to include all Firebase modules by using pod ‘Firebase’ or just add modules for Push Notification only by using:

pod 'Firebase/Core'
pod 'Firebase/Messaging'

Then do pod install to have CocoaPods gets and setups dependencies for you.

Initialization Code

After installed CocoaPods dependencies, you should use your .xcworkspace to open your XCode project. We do some intialization first for our Firebase setup.

First, go to your AppDelegate.swift file, and import and configuration statement for Firebase:

import Firebase

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  ...
  FIRApp.configure()
  ...
  return true
}

You can test the configuration by running the app, and see Firebase outputs a bunch of log lines like this:

2016-08-22 10:10:17.367 Aster[5655:64486] Configuring the default app.
2016-08-22 10:10:17.428 Aster[5655:20] <FIRAnalytics/INFO> Firebase Analytics v.3300000 started
2016-08-22 10:10:17.430 Aster[5655:20] <FIRAnalytics/INFO> To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see http://goo.gl/Y0Yjwu)
2016-08-22 10:10:17.438: <FIRInstanceID/WARNING> FIRInstanceID AppDelegate proxy enabled, will swizzle app delegate remote notification handlers. To disable add "FirebaseAppDelegateProxyEnabled" to your Info.plist and set it to NO
2016-08-22 10:10:17.442: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "The operation couldn’t be completed. (com.firebase.iid error 1001.)"
2016-08-22 10:10:17.459: <FIRMessaging/INFO> FIRMessaging library version 1.1.1
2016-08-22 10:10:17.467 Aster[5655:20] <FIRAnalytics/INFO> Successfully created Firebase Analytics App Delegate Proxy automatically. To disable the proxy, set the flag FirebaseAppDelegateProxyEnabled to NO in the Info.plist
2016-08-22 10:10:17.495: <FIRMessaging/WARNING> FIRMessaging AppDelegate proxy enabled, will swizzle app delegate remote notification receiver handlers. Add "FirebaseAppDelegateProxyEnabled" to your Info.plist and set it to NO
2016-08-22 10:10:18.097: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=NSCocoaErrorDomain Code=3010 "remote notifications are not supported in the simulator" UserInfo=0x7bf8aed0 {NSLocalizedDescription=remote notifications are not supported in the simulator}
2016-08-22 10:10:28.449 Aster[5655:20] <FIRAnalytics/INFO> Firebase Analytics enabled

Device Token

Put the following code in your application:didFinishLaunchingWithOptions: method, or any piece of code you want your push to start being handled:

  let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
  UIApplication.sharedApplication().registerUserNotificationSettings(settings)

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
  application.registerForRemoteNotifications()
}

Add the following code to your Delegate too, to enable Firebase with your device token. This should work on real device only:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
  #if DEBUG
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .Sandbox)
  #else
    FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .Prod)
  #endif
}

Certificate

As you can see, Firebase reports that it can not fetch token due to push notification does not work on simulator. To test the notification on real devices, we need a certificate. Now follow Create Certificate for iOS Push Notification tutorial to create certificates for your app. Then go to Keychain Access app, right click on your certificate(s) and choose Export.. Enter your desired password to get certificate(s) in form of .p12 file(s).

Then go to your Firebase iOS app, upload two certificates and enter the password you have put earlier.

FCM_iOS_Cert

Test the Notification

Now you are ready to test your Firebase Cloud Message iOS. Run the app on real device, then go to Firebase Console, create a message and send:

FCM_iOS_TestResult:

FCM_iOS_Result

That’s it. Now you can try to play with various settings from Firebase console and start integration between your backend and the Firebase. Our Firebase series is continuing, stay tuned!.