Skip to main content
The UIKit iOS push sample shows how to layer FCM on top of APNs so messages and calls arrive in foreground, background, and terminated states. Follow these steps to replicate it.

Reference implementation

Browse the iOS push sample (UIKit + Calls + FCM/APNs/PushKit).
Paths below refer to the sample repo (for example examples/push-notification-app/AppDelegate.swift and helper files that manage Firebase Messaging, APNs tokens, and CallKit). Copy the flow, then swap bundle ID, Team ID, and provider IDs.

Architecture map

Sample pathRoleWhat to copy/replicate
AppDelegate.swiftInitializes CometChat, configures Firebase, sets UNUserNotificationCenterDelegate, registers for remote notificationsMirror init + delegate wiring; ensure Messaging.messaging().delegate is assigned.
Firebase/FCM helper (token manager)Requests notification permission, obtains FCM token, registers it with CometChat Push NotificationsReuse token handling and registration calls; update provider ID.
PushKit/CallKit helpersPresents native incoming-call UI from VoIP pushes (recommended even when using FCM for messages)Keep VoIP registration + CallKit accept/decline wiring.

1. Prerequisites

  • Firebase project with an iOS app added; GoogleService-Info.plist in your Xcode target; APNs key uploaded under Project Settings → Cloud Messaging.
  • Apple Developer entitlements: Push Notifications, Background Modes (Remote notifications, VoIP), CallKit usage descriptions.
  • CometChat app credentials and Push Notifications extension enabled with:
    • FCM iOS provider ID for data pushes.
    • Optional APNs device and APNs VoIP provider IDs if you want direct APNs/PushKit delivery (recommended for call reliability).
  • Physical iPhone/iPad for testing; FCM + VoIP pushes are unreliable on simulators.

Dashboard settings (Push Notifications extension)

  • Set Extension version to V2 (or V1 & V2 during migration).
  • Select Platforms: enable iOS.
  • Enter your FCM iOS provider ID; add APNs providers if you plan to register those tokens too.
  • Use Payload trimming if payloads risk exceeding ~4 KB; toggle Notification triggers as needed.

2. Firebase + iOS configuration

  1. Add GoogleService-Info.plist to the app target.
  2. In Project Settings → Cloud Messaging, upload your APNs auth key/cert so FCM can deliver via APNs.
  3. In AppDelegate, call FirebaseApp.configure() and set Messaging.messaging().delegate = self.
  4. Request notification permission via UNUserNotificationCenter, set its delegate, and call UIApplication.shared.registerForRemoteNotifications().

3. Register the FCM token with CometChat

After the user logs in, register the FCM token with CometChat Push Notifications:
Messaging.messaging().token { token, error in
    guard let token = token else { return }
    CometChatNotifications.registerPushToken(
        token: token,
        platform: .fcmIos,                 // use the FCM iOS platform enum
        providerId: "<FCM_PROVIDER_ID>"
    ) { _ in
        print("FCM token registered")
    } onError: { error in
        print("FCM register error: \(error?.errorDescription ?? "")")
    }
}

// Handle token rotation
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
    guard let token = fcmToken else { return }
    // Re-register with CometChat here
}
  • Keep APNs device/VoIP registration (via didRegisterForRemoteNotificationsWithDeviceToken and PushKit) if you also use APNs providers for calls.

4. Handling incoming pushes

Message pushes (FCM)

  • Foreground: handle in userNotificationCenter(_:willPresent:) and decide banner/alert options.
  • Background/terminated: taps arrive in userNotificationCenter(_:didReceive:...); parse userInfo and navigate to the correct chat. If you include the message JSON, convert it with CometChatHelper.processMessage.
  • For richer UI, you can add a Notification Service extension; otherwise, FCM→APNs payload will show default alert/sound.

Call pushes (recommended: PushKit)

  • Use PushKit (PKPushRegistry) to register a VoIP token and register it with CometChat using the APNs VoIP provider. This enables reliable CallKit UI even when the app is killed.
  • In pushRegistry(_:didReceiveIncomingPushWith:), convert payloads to Call objects and report them to CallKit (CXProvider.reportNewIncomingCall). Accept/Decline through CometChat acceptCall / rejectCall.

5. Customizing the notification body

Set metadata["pushNotification"] before sending to override the body:
var metadata = ["pushNotification": "Custom notification body"]
let custom = CustomMessage(receiverUid: "TARGET_UID",
                           receiverType: .user,
                           customType: "your_type",
                           customData: ["key": "value"])
custom.metadata = metadata
CometChat.sendCustomMessage(message: custom) { _ in } onError: { _ in }

6. Testing checklist

  1. Verify FirebaseApp.configure() runs and FCM token logs after login; ensure registration succeeds with CometChat.
  2. Send a dashboard message push:
    • Foreground: confirm willPresent behavior.
    • Background/terminated: tap opens the correct chat.
  3. Rotate the FCM token (didReceiveRegistrationToken) and confirm re-registration works.
  4. If using VoIP: confirm PushKit token registration and that CallKit UI appears for call pushes; Accept/Decline should control the CometChat call.

7. Troubleshooting

SymptomQuick checks
No FCM pushesConfirm GoogleService-Info.plist placement, APNs key uploaded to Firebase, bundle ID matches, permission granted.
Token registration failsEnsure it runs after login, provider ID matches the FCM iOS provider, and Messaging.messaging().delegate is set.
Taps ignoredVerify UNUserNotificationCenterDelegate methods run and navigation is ready before routing.
Call UI missingAdd PushKit + CallKit setup and register a VoIP token with an APNs VoIP provider.

Additional resources