Firebase Cloud Messaging for iOS: Push Notifications
Learn how to use Firebase Cloud Messaging to send and receive remote push notifications in your SwiftUI iOS app. By Andy Pereira.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Firebase Cloud Messaging for iOS: Push Notifications
25 mins
- Getting Started
- Configuring Firebase
- Creating the p8 Certificate
- Setting up the Firebase Project
- Adding the Package
- Configuring Your App
- Launching Firebase
- Registering for Notifications
- Sending Notifications
- Sending Data in Notifications
- Subscribing to Topics
- Sending Images
- Adding a Notification Service Extension
- Customizing Notifications
- Analytics
- Tracking Custom Events
- Where to Go From Here?
Subscribing to Topics
Another feature of Firebase Cloud Messaging is subscribing to a topic, which is a great way to give your users flexibility in customizing notifications. Firebase lets you tag specific push notifications with topics. You can then subscribe your users to different topics. For instance, maybe users are interested in critical notifications like direct messages but don’t need to be informed of new posts on your app’s feed. Or, you can let your users follow specific posts or people, receive push notifications for group chats, etc.
Fortunately, this is easy to do. First, open TopicsModel.swift and add the following import at the top:
import FirebaseMessaging
The starter project includes a switch that lets users toggle topics they are interested in. You’ll connect those switches to Firebase.
Replace subscribe(to:)
and unsubscribe(from:)
with the code below:
private func subscribe(to topic: String) {
// 1
Messaging.messaging().subscribe(toTopic: topic)
}
private func unsubscribe(from topic: String) {
// 2.
Messaging.messaging().unsubscribe(fromTopic: topic)
}
That’s it! Here’s what you added:
- When the user turns a topic switch on, this code will ask Firebase to subscribe to that topic.
- When the user turns a topic switch off, this code will ask Firebase to unsubscribe from that topic.
Build and run. Then, go to the Topics tab and turn on the Pets toggle.
In the console, duplicate the notification from the previous step by selecting the three dots on the far right of the notification:
Leave everything the same, except for Step 2. Change User Segment to Topic, and enter pets for the Message topic:
This will now only send notifications to the users who have turned on the Pets toggle. Send the notification, and you’ll see everything work like it did in the previous section. Duplicate the notification again, and change the topic to family and send it. Since your app isn’t subscribed to the topic, Firebase won’t send the notification to your device.
Sending Images
Up to this point, your notifications have all contained only text. But if you’ve received many notifications, you know that notifications can have rich content, such as images. It’d be great if your notifications showed users a nice image related to their content. Once again, Firebase makes this super simple.
Adding a Notification Service Extension
To show an image in push notifications, you’ll need to create a Notification Service Extension. This is a separate target in your app that runs in the background when your user receives a push notification. The service extension can receive a notification and change its contents before iOS shows the notification to the user. You’ll use Firebase to send an image URL inside a notification. You’ll then use a content extension to download the image and add it to the notification’s content.
In Xcode, go to File ▸ New ▸ Target…. Search for Notification Service Extension and select Next. Set the name to Good News Notifications and configure it to add to the project Good News and embed in the application Good News, as in the screenshot below:
Select Finish, and when prompted, select Activate.
When you added the Firebase package to your project, it was only added to the Good News target, so now you need to add the necessary dependency to your new extension. Open your app’s project settings and select Good News Notifications under Targets. Under Frameworks and Libraries, select the + button, and search for FirebaseMessaging. Then, select Add. Your project should reflect the image below:
Customizing Notifications
Now, open NotificationService.swift. This file is where you can customize notifications before the user sees them.
First, add the following import to the top of the file:
import FirebaseMessaging
Next, replace the contents of didReceive(_:withContentHandler:)
with the following:
self.contentHandler = contentHandler
bestAttemptContent = request.content
.mutableCopy() as? UNMutableNotificationContent
guard let bestAttemptContent = bestAttemptContent else { return }
FIRMessagingExtensionHelper().populateNotificationContent(
bestAttemptContent,
withContentHandler: contentHandler)
Typically, you’d have to search out the field that contains the image URL, download the image, and then finish the presentation with the image as an attachment. Here, you’re using Firebase’s FIRMessagingExtensionHelper
to automatically perform all that work in one simple helper method call.
Keep in mind, iOS only gives you a limited amount of time to download your attached image. If the extension’s code takes too long to run, the system will call serviceExtensionTimeWillExpire()
. This gives you a chance to gracefully finish up anything you are doing in the extension or to simply present the notification as is, which is the default implementation.
Ensure Good News is your active target, then build and run. The app should look the same as before.
Back in the Firebase Cloud Messaging console, duplicate the same notification about kittens you’ve been using for the last few steps. Make sure you don’t use the one with the topic set to family, since your app isn’t subscribed to that topic.
This time, in Step 1 under Notification image, add the following URL: https://koenig-media.raywenderlich.com/uploads/2021/01/good_news_petsicon.png.
Your console should appear as below:
Send your notification. On your device, you’ll see a notification come through with a picture of a kitten, as shown below:
Analytics
Now that you’re sending and processing notifications, consider the importance of understanding how users are interacting with your notifications. Are they ignoring them altogether? Do they open them regularly? With Firebase Analytics and Cloud Messaging, you can track the events surrounding your notifications.
Up until now, you’ve been missing one step to processing your notifications: informing Firebase that you received them. In AppDelegate.swift, add the following to process(_:)
at the end of the method:
Messaging.messaging().appDidReceiveMessage(userInfo)
Build and run. Then, stop debugging and close your app. Next, duplicate your previous notification in the Cloud Messaging console and send it. When you get the notification, tap it to open your app.
Open the notification in the Cloud Messaging console. It will show a count for Sends, as below:
Tracking Custom Events
Now that your app is informing Firebase that it received the notification, there might also be a count for Opens. However, it’s unlikely you’ll see this number increase. It can take up to 24 hours before you see analytic information get processed and presented to you in the Firebase console. In fact, you may never actually see this number increase at all, even after that. At the time of writing, there are limitations on what Google can report back for iOS and Android notifications. That’s OK, though — you can still take advantage of Analytics and track custom events.
In AppDelegate.swift, add this line of code in process(_:)
, right after NewsModel.shared.add([newsItem])
:
Analytics.logEvent("NEWS_ITEM_PROCESSED", parameters: nil)
This code uses Firebase’s Analytics
to track that you added a news item to your feed. Now, add this line of code, right after Messaging.messaging().appDidReceiveMessage(userInfo)
:
Analytics.logEvent("NOTIFICATION_PROCESSED", parameters: nil)
This logs an event saying that you processed the notification, whether or not it contained a news item.
Build and run. Once again, duplicate your notification in the Cloud Messaging console and send it. Back in Firebase, choose Events under Analytics. Here, you’ll start to see your events show, like below:
In this example, you only see an entry for NEWS_ITEM_PROCESSED. This is because Google hasn’t yet finished processing the analytics for the app. Again, it’s unlikely you’ll see either of these events logged in your account as you follow along with the tutorial. Let several hours to one day pass, and check again.