Skip to main content

Firebase and FCM Token

The SDK does not include Firebase. Your app owns Firebase Cloud Messaging and passes the FCM token to the SDK, which registers it on the current contact. How push delivery works in general: Push Notifications.


Requirements​

  • SDK 1.0.0 or later. Versions 0.7.x bundled Firebase, see the Migration Guide.
  • Firebase Cloud Messaging added to your app, see the Firebase guide.
  • An APNs authentication key uploaded to the same Firebase project, see the Firebase guide.
  • The same Firebase project's service account key uploaded to the Positive User panel.

Setup​

  1. Configure Firebase and set the messaging delegate as described in the Firebase guide.

  2. Pass every token Firebase reports to the SDK:

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
    guard let fcmToken else { return }
    UserSDK.default?.setFcmToken(fcmToken)
    }
  3. When a contact logs in, pass the token together with the identity. See Login and logout.

The SDK keeps the token only for the lifetime of the process. Pass it again on every launch, which didReceiveRegistrationToken already does in a standard Firebase setup.

Check

After the first launch with a token, a push notification sent to this contact arrives on the device. The panel does not show the push token itself. To check that devices have one, go to Data → Contacts and filter contacts by FCM key with the condition has any value.


Ways to pass the token​

All of these store the token and attach it to pings. Pick the one that matches the moment you have the token.

WhenCallSends a ping
Token known at launchUserSDK(application:apiKey:baseURL:shouldTrackActivities:fcmToken:)No. Call ping() yourself.
Token arrives or rotatessetFcmToken(_:)Yes, except while logout is in progress
You ping anywayping(fcmToken:_:)Yes, this call is the ping
Login or profile updateupdateContact(_:fcmToken:_:)Yes, contact data and token in one request

Login and logout​

At login, send the contact data and the token in one call:

let contact = Contact(userId: "12345", email: "jane@example.com")
UserSDK.default?.updateContact(contact, fcmToken: token)

Two separate calls (updateContact and then setFcmToken) send two pings, and a retried ping can reach the backend after the other one. One call avoids that.

At logout, pass the token you want to remove from the contact who is leaving:

UserSDK.default?.logout(fcmToken: token) { success, error in
// a new anonymous contact is ready
}

The anonymous contact created by logout gets the same token, so the device keeps receiving push notifications. Turning them off after logout is up to your app. Details: Contacts.

Changed in 1.3.0

Before 1.3.0 the anonymous contact created by logout had no token, and the device received no push notifications until the next login or setFcmToken(_:). From 1.3.0 it keeps the token. A push notification sent to the logged out contact does not reach the device. If you call setFcmToken(_:) after logout only to keep push notifications, remove that call.


Firebase method swizzling​

Firebase replaces some app delegate methods at runtime by default (method swizzling). The SDK works with swizzling on or off. What changes is the code your app writes.

FirebaseAppDelegateProxyEnabled in Info.plistWhat your app does
Not set or YES (default)Firebase maps the APNs token to the FCM token for you. Forward notifications to the SDK as in Installation, Step 6.
NOYour app sets Messaging.messaging().apnsToken in application(_:didRegisterForRemoteNotificationsWithDeviceToken:) and calls Messaging.messaging().appDidReceiveMessage(_:) for incoming notifications. Forward notifications to the SDK the same way.

The details of both modes are in the Firebase guide. In both modes, application(_:didReceiveRemoteNotification:fetchCompletionHandler:) must call UserSDK.default?.handleNotification(_:), otherwise in-app messages are not shown.


Methods​

setFcmToken(_:)​

Stores the FCM token and sends a ping, which registers the token on the current contact. Call it whenever Firebase reports a new token.

NameTypeRequiredDescription
tokenStringYesThe FCM registration token from Firebase.

Returns nothing. The ping goes through the SDK's request queue.

UserSDK.default?.setFcmToken(fcmToken)
Changed in 1.2.0

setFcmToken(_:) sends a ping on every call, also when the token has not changed. Earlier versions ignored a repeated token. If you call it on each launch or after each login, expect one ping per call.

The other methods that accept a token are described with their topic: ping(fcmToken:_:), updateContact(_:fcmToken:_:), logout(fcmToken:_:).


Common errors​

SymptomCauseFix
The contact cannot be selected in a push campaignThe contact has no device with a push token: no FCM token was passed to the SDK, or the token moved to another contact that later used the same device.Call setFcmToken(_:) from messaging(_:didReceiveRegistrationToken:).
Firebase reports no token or an APNs errorNo APNs key in Firebase, or the Push Notifications capability is missing.Upload the APNs key in Firebase, see the Firebase guide, and add the capability.
Delivery fails with a sender ID mismatchThe app uses a different Firebase project than the service account key in the panel.Upload the service account key of the project in your app's GoogleService-Info.plist.
No token with FirebaseAppDelegateProxyEnabled set to NOFirebase does not know the APNs token.Set Messaging.messaging().apnsToken in application(_:didRegisterForRemoteNotificationsWithDeviceToken:).
Push notifications go to the previous contact after logoutlogout was called without the token.Pass the token: logout(fcmToken: token).
The anonymous contact after logout cannot be selected in a push campaignSDK earlier than 1.3.0: the anonymous ping carries no token.Update to 1.3.0, or call setFcmToken(_:) after logout completes.