This post covers setting up and running push notifications, addressing a common yet often confusing aspect of app development. Many developers, especially beginners, struggle with configuring Apple Push Notification Service (APNs), handling authentication keys, and managing payloads. A well-structured guide can simplify these steps, offer troubleshooting insights, and help developers avoid common pitfalls.

Push notifications are crucial for user engagement, making it essential to implement them effectively. This tutorial aims to provide a clear, step-by-step approach to help developers integrate push notifications, ultimately improving app retention and user experience.

In this post, we will set up push notifications using Firebase and implement a basic iOS app that receives them.

The blank iOS Push Notifications ready app project

Create a blank project:

I stop at this point just to notice de ‘Bundle Identifier’ because we will nee it further on. Open target settings:

Add Push Notifications and Background Modes:

And check ‘Remote notifications:

Generating keys on Apple Developer portal

For generating keys, it is mandatory to have an Apple Developer Account (or higher-tier subscriptions). Go to Certificates, Identifiers & Profiles section

Add a new key (+). Fill in a key name:

And check ‘Apple Push Notifications service (APNs).

Continue

Important: Two things to note: keep track of the Key ID and download the .p8 key; you will need both later. And last but not least:

Take note of your Team ID by visiting your Apple Developer Account. For the next step, you will need the following:

  • App Bundle ID
  • .p8 key file
  • Key ID
  • Team ID

Firebase

To continue, you will need a Firebase account and create a new project.

Fulfill Google Analytics account and location:

Setup iOS app Configuration

Time to fill iOS App bundle:

Next step will present us SPM GitHub url:

Add SPM package in XCode:

Add FirebaseMessaging to your target:

In this case, since we are only using Firebase’s Push Notification service, we only need FirebaseCore as a base and FirebaseMessaging itself. The final step involves the Firebase wizard providing the code to start working with the iOS app.

During this process, you will be provided with the GoogleService-Info.plist file. Keep it, as you will need to incorporate it into your iOS app’s source code.

iOS app ready to receive pushes

Add the GoogleService-Info.plist configuration file generated in the previous Firebase configuration step. For security reasons, the GoogleService-Info.plist file will not be uploaded to the GitHub repository.

This is AppDelegate implementation:

import SwiftUI
import FirebaseCore
import UserNotifications
import FirebaseMessaging

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        
        UNUserNotificationCenter.current().delegate = self
        Messaging.messaging().delegate = self
        
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
            if granted {
                print("Graned permission for receiving notifications")
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            } else {
                print("Permision denied for receiving notifications")
            }
        }
        
        return true
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        print("APNs Token: \(token)")

        Messaging.messaging().apnsToken = deviceToken
    }
    
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        if let fcmToken = fcmToken {
            print("FCM Token: \(fcmToken)")
        }
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.banner, .sound])
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        completionHandler()
    }
}

@main
struct PushNotificationsSampleApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
  }

This SwiftUI code configures an iOS app to handle push notifications using Firebase Cloud Messaging (FCM). It initializes Firebase, requests user permission for notifications, and registers the app with Apple Push Notification service (APNs) to receive device tokens. The AppDelegate class handles FCM token updates, displays notifications when the app is in the foreground, and manages user interactions with those notifications. The app’s main entry point links the AppDelegate to the SwiftUI lifecycle and sets up the initial view. This setup enables the app to receive and display push notifications, making it suitable for use cases such as messaging, social media, or e-commerce apps.

When building the app for the first time, the user will be prompted to allow notifications.

Please say Allow, if all was setup ok in the logs you will find FCM token printed:

The FCM token (Firebase Cloud Messaging token) is a unique identifier assigned by Firebase to each device instance of your app. It is used to reliably deliver push notifications to specific devices. Be sure to keep track of this value, as you’ll need it later.

Send Push Notification

Now it’s time to check if everything was set up correctly by sending a push notification. Go back to the Firebase Console.

Open project settings menu option and select Messaging tab.

Upload the .p8 key file generated from the Apple Developer portal, along with the Key ID and Team ID values. Then, navigate to the ‘Messaging’ sidebar option.

Fill in notification title and text and press send message:

Fill in notification title and text and press send message:

Finally paste FCM token that you got from XCode log, press Test and:

Voila! here you go!

Conclusions

Setting up push notifications is typically a one-time implementation with minimal ongoing maintenance. However, it’s easy to make mistakes. The intention of this post is to present a simple way to set up push notifications if you’ve never encountered them before.

You can find the source code used for this post in the repository linked below.

References

Copyright © 2024-2025 JaviOS. All rights reserved