I was able to figure out how to send data-only FCM push messages to SwiftUI after assembling a bunch of scattered bits of information.
The FCM on iOS guide is a good place to start. Do everything there and come back here to fill in the cracks and finish the data notification implementation.
You'll notice that for SwiftUI it asks you to set FirebaseAppDelegateProxyEnabled
to NO
in Info.plist. In modern XCode projects this won't be an actual file called Info.plist, it will be the "Info" tab under the your target in the project settings. Also, uncomment all the "if disabling method swizzling" in the example code.
You won't need to call UNUserNotificationCenter.requestAuthorization()
to get data messages, only to fire notifications if you decide to when acting on them.
Capabilities
Under Signing and Capabilities in your project you'll need Background Modes -> Remote notifications checked, and Push Notifications added.
Sending messages from the server
After sending your device's FCM token to the server, you can fire off the data messages by calling the FCM v1 HTTP endpoint:
POST https://fcm.googleapis.com/v1/projects/<project_id>/messages:send
{
"message": {
"data": {
"your": "data"
},
"token": "abc_def",
"apns": {
"headers": {
"apns-push-type": "background",
"apns-priority": "5",
"apns-topic": "com.example.MyApp"
},
"payload": {
"aps": {
"content-available": 1
}
}
}
}
}
token
: Your FCM token
apns-topic
: Your app's bundle ID
This instructs FCM to create the appropriate request for APNs, as documented in Generating a remote notification.
The apns-push-type
header tells it that it can arrive in the background. The apns-priority
is 5 because that's required for background notifications. content-available
in the payload tells it that it will not be accompanied by any notification, so we don't have any alert
, sound
or badge
keys in the payload.
Handling the messages
I ended up getting the messages on the async method from the example:
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
-> UIBackgroundFetchResult
Top comments (0)