iOS Push Notifications: Part 5 — Firebase

Dmitrijs Beloborodovs
Citadele Bank Developers
5 min readMar 21, 2024

There are many third party services helping to integrate push notification sending across different platform (Android & iOS) with your backend. Let’s review one of the most popular — Firebase.

One crucial thing to understand: Firebase (same is true for any other service) won’t sent notification directly to mobile device, eventually it will contact APNs. Think of it as a proxy which solves some technical difficulties you don’t want to deal with. As you know, every device has a unique push notification token (an address of your device). After registering app send it to your backend. And your backend use it to send pushes via APNs. Since in iOS there is no callback when user uninstall app, you don’t really know if user still use your app. But you keep sending pushes. APNs will try to respond accordingly and you must stop sending pushes to that token. If not, at some point APNs block your IP. No more pushes to any of your clients. Firebase not only solve this problem, but gives more benefits: topics (virtual groups of clients), nice WEB console and easy integration on backend.

Let’s add Firebase to our iOS project and setup project on Firebase console.

Firebase Console

Obviously, to use Firebase, you need Google account.

Navigate to https://console.firebase.google.com/project and create a new project

Select your Google account from dropdown.

We must upload Key from Apple Developer portal to allow Firebase portal send pushes to our app. Open Firebase Console → Project Overview → Project Setting → Messaging

Scroll down to where you can upload key (or add certificate, depending on how you decided to authorise on APNs)

Once finished open Engage → Messaging

Now you need to add integration with iOS project

Add your app bundle ID, app nickname and App Store ID, if any.

Very important, download GoogleService-Info.plist to your Xcode project folder.

Xcode Project Setup

Add SPM package with:

https://github.com/firebase/firebase-ios-sdk.git

Add products you want use. For push notification we need FirebaseMessaging

Initialise Firebase library in app launch delegate method:

import FirebaseCore
import FirebaseMessaging

class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
// ... subscribe to push notifications
return true
}
}

Initialise Firebase library BEFORE you subscribe to push notifications. Configure Firebase delegate. Add following line just after initialising Firebase library:

Messaging.messaging().delegate = self

Very important step. Add FirebaseAppDelegateProxyEnabled to app Info.plist and set to NO.

As you know push notification token is an “address” of device from APNs point of view. Firebase add it’s own identifier. In different time in different documentation it has various names: token, identifier, etc. I call the way it was time ago and make sense: FCM ID. Push notification token may change in time, same as FCM ID, so it’s vital to keep match between them. So, whenever token updates, Firebase need to know it. Add the following to delegate method:

func application(application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}

Your backend needs to know FCM ID to be able to send pushes. So, Whenever it changes you need to inform your server. Luckily, there is a delegate method in Firebase library, just add it to you app delegate class:

// MARK: - MessagingDelegate
extension AppDelegate: MessagingDelegate {

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("\(#function)\nFirebase registration token: \(String(describing: fcmToken))")
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
}

Sending First Firebase Push Notification

Get to Firebase console:

Let’s send simple push to our device only

Launch iOS app. FCM ID should be printed in console (if not, see link to source code):

Topics

Very powerful concept. Instead of sending push to every single device, you may organise groups. Think of “topics” as “channels”. None or all customers may subscribe to many topics, and you don’t need to track that. Firebase will do it for you. Just sent dedicated push to those subscribed.

API is very simple:

    func subscribeToTopic() async {
try? await Messaging.messaging().subscribe(toTopic: "payments")
}

func unsubscribeFromTopic() async {
try? await Messaging.messaging().unsubscribe(fromTopic: "payments")
}

That’s all you need to know to integrate Firebase Messaging into iOS project.

Feel free to play with source code.

References

--

--