FCMDebug logoFCMDebug

FCM with iOS

Set up Firebase Cloud Messaging for push notifications in your iOS app using Swift.

Prerequisites

  • Xcode 16.2+
  • An Apple Developer account (paid — required for APNs)
  • A physical iOS device (push notifications don't work on simulators)

Setup

1. Add Firebase SDK

In Xcode, navigate to File → Add Package Dependencies… and enter:

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

Select FirebaseMessaging and click Add Package.

2. Download GoogleService-Info.plist

  1. Go to Firebase Console → select your project
  2. Click ⚙️ gear iconProject settingsGeneral tab
  3. Under "Your apps," select your iOS app and click Download GoogleService-Info.plist
  4. Drag the file into the root of your Xcode project and make sure "Add to targets" is checked

3. Configure APNs in Firebase

  1. Go to Project settingsCloud Messaging tab
  2. Under "Apple app configuration," click Upload next to APNs authentication key
  3. Upload your .p8 key file, then enter your Key ID and Team ID

4. Enable Push Notifications in Xcode

  1. Select your project target
  2. Go to Signing & Capabilities
  3. Click + Capability and add Push Notifications
  4. Also add Background Modes and check Remote notifications

5. Initialize Firebase

UIKit (AppDelegate)

swift
import UIKit
import FirebaseCore
import FirebaseMessaging

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        UNUserNotificationCenter.current().delegate = self

        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in
            guard granted else { return }
            DispatchQueue.main.async {
                application.registerForRemoteNotifications()
            }
        }

        return true
    }

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

SwiftUI

If you're using SwiftUI, create an AppDelegate class and attach it using @UIApplicationDelegateAdaptor:

swift
import SwiftUI
import FirebaseCore
import FirebaseMessaging

@main
struct YourApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

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

class AppDelegate: NSObject, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        UNUserNotificationCenter.current().delegate = self

        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in
            guard granted else { return }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }

        return true
    }

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

6. Get FCM Token

swift
extension AppDelegate: MessagingDelegate {
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("FCM Token: \(fcmToken ?? "")")
        // Send to your server
    }
}

7. Handle Notifications

swift
extension AppDelegate: UNUserNotificationCenterDelegate {
    // Foreground notification
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
        let userInfo = notification.request.content.userInfo
        print("Foreground notification: \(userInfo)")
        return [[.banner, .badge, .sound]]
    }

    // Notification tapped
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse) async {
        let userInfo = response.notification.request.content.userInfo
        print("Notification tapped: \(userInfo)")
    }
}

Silent Notifications

Silent (data-only) notifications wake your app in the background:

swift
func application(_ application: UIApplication,
                 didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async -> UIBackgroundFetchResult {
    print("Silent notification: \(userInfo)")
    return .newData
}

To send a silent notification via the FCM HTTP v1 API, set content-available: 1 inside the APNs payload:

json
{
  "message": {
    "token": "DEVICE_TOKEN",
    "apns": {
      "payload": {
        "aps": {
          "content-available": 1
        }
      }
    }
  }
}

Make sure Background Modes → Remote notifications is enabled in Xcode, or the silent notification won't wake your app.

Testing

  1. Run the app on a physical device and copy the FCM token from the Xcode console

  2. Open the FCM Tester

  3. Paste your service account JSON and the device token

  4. Send a test notification

Common Issues

IssueFix
No token receivedCheck APNs key is uploaded in Firebase Console → Cloud Messaging tab
Notifications not showing on simulatorPush notifications require a physical device
Permission deniedUser denied notification permission — consider showing a custom pre-prompt before calling requestAuthorization
Badge not updatingSet the badge count in the APNs payload (aps.badge)
Silent notification not firingEnable Background Modes → Remote notifications in Xcode capabilities
SwiftUI app not receiving notificationsUse @UIApplicationDelegateAdaptor to connect your AppDelegate

Related

Was this page helpful?