[iOS] Remote Notification with Firebase Tutorial

I am going to show you how to setup Remote Notification in iOS using Firebase. It is not new topic for iOS and there is always new change of APIs or new libraries. If you are junior developer, this tutorial may help you. If you are senior, it is also nice to have a recap.

Let’s go.

Environment: iOS 10 & 9, Swift 3.1, Xcode 8.3.3


Installing Firebase

I would prefer to install Firebase using CocoaPods

PodFile:

source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
platform :ios, '9.3'
def base_pods
pod 'Firebase/Core'
pod 'Firebase/Messaging'
pod 'Firebase/Crash'
end
target "RemoteNotificationDemo" do
base_pods
end

pod install and run your Xcode workspace


Preparing Certificate

To enable Push Notification for your iOS App:

  • Setup your Team, Profiles and Certificates in Target -> General
    or simply use Automatically manage signing by Xcode
  • Tune on Push Notifications in Target -> Capabilities

You should see two ticks:

p.s. Sometime Xcode may fail to manage your app. Then you need to go Apple Developer Console (https://developer.apple.com/) to turn on the app’s Push Notification:

  • Create APNs Auth Key in Keys

Configuration with auth keys is recommended as they are the more current method for sending notifications to iOS. Advantages of Auth Key:

  1. No need to re-generate the push certificate every year
  2. One auth key can be used for all your apps

But you can still use the old way: Creating Development and Production SSL Certificates

ps. Once you downloaded the Auth Key, it will not able to re-download from Developer Console. So you should back-up it.


Now we are going to create Firebase account.

  • Download the GoogleService-Info.plist
  • Go to Settings -> CLOUD MESSAGING. Upload your created Auth Key.

Coding

The setup are quite simple:

  1. FirebaseApp.configure()
  2. application.registerForRemoteNotifications()
  3. requestNotificationAuthorization(application: application)
    You may call this only when the user know why your app need their notification authorization.

Keep in mind that you should always aware the application status (active, background or inactive) of the app when you receiving remote notification. You should handle them differently in these cases. Also different callbacks are used for iOS9 and iOS10.

iOS9:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any])

This will be called for both case:

  • Remote Notification is received when the status is active.
  • Remote Notification is opened when the status is non-active.

If the app is terminated and user open the remote notification, the notification info is inside launchOptions in didFinishLaunchingWithOptions.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
...
if let userInfo = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] {
NSLog("[RemoteNotification] applicationState: \(applicationStateString) didFinishLaunchingWithOptions for iOS9: \(userInfo)")
//TODO: Handle background notification
}
return true
}

Notes:

  • NO notification will appear on device’s notification center when receiving remote notification in active state. You may need to present your notification in your own way.
  • The app’s UIs is not ready yet when receiving remote notification in non-active state. If you need to present or push view controllers based on the content of notification. You need to save the content of notification and handle it until UIs are all ready.

iOS10:

// iOS10+, called when presenting notification in foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
// iOS10+, called when received response (default open, dismiss or custom action) for a notification
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)

In iOS10, two callback are used for two cases.

Notes:

  • Notification will appear on device’s notification center when receiving remote notification in active state. So you don’t need to add your UI to handle this case.
  • The app’s UIs is not ready yet when receiving remote notification in non-active state. If you need to present or push view controllers based on the content of notification. You need to save the content of notification and handle it until UIs are all ready.

Data in notification

This is an example of remote notification sent using Firebase. In most of the time, the content of notification is needed for handling it.

[AnyHashable("google.c.a.e"): 1, AnyHashable("google.c.a.ts"): 1500259554, AnyHashable("google.c.a.udt"): 0, AnyHashable("userId"): 1234, AnyHashable("gcm.n.e"): 1, AnyHashable("aps"): {
alert = hi8;
}, AnyHashable("google.c.a.c_id"): 5530879855980421587, AnyHashable("gcm.message_id"): 0:15002595552428880.000000e+00e9743a2ee9743a2]

In this notification, a custom data (userId = 1234) is sent. (Configured in notification sender in Firebase) And the message of notification is inside aps.alert.


That’s all. It’s not a complicated thing in iOS. But you should always aware the application status when handling the notifications.

Show your support

Clapping shows how much you appreciated Roy Ng @ Redso’s story.