Swift 4中App关闭时Firebase REST API推送通知无法正常工作
Hey there! Let's break down why your Firebase REST API push notifications only pop up when your iPhone app is open, while sending directly from the Firebase Console works flawlessly. I’ve tackled similar issues before, so here are the key fixes and checks to try:
1. Fix Your REST API Payload Structure
The Firebase Console automatically handles the correct payload format for APNs, but when using the REST API, you need to explicitly structure it to trigger system-level notifications (even when the app is in the background).
Critical Distinction: Notification vs Data Messages
- Notification messages: Include a
notificationfield—APNs will automatically display these to the user regardless of whether the app is foregrounded or backgrounded. - Data messages: Only include a
datafield—these won’t trigger a system alert when the app is in the background; you’ll need to manually handle them in your app code.
Correct Payload Example
{ "to": "YOUR_DEVICE_FCM_TOKEN", "notification": { "title": "Hey there!", "body": "This is a test notification from Firebase REST API" }, "apns": { "payload": { "aps": { "sound": "default", "badge": 1 } } } }
If you need to include custom data alongside the notification, add a data field to the payload—APNs will still display the system alert, and your app can access the data when opened.
2. Set the Correct APNs Priority
Without explicit priority settings, your REST API messages might be throttled or delayed by APNs, especially when the app is in the background. Add the apns-priority header to ensure immediate delivery:
{ "to": "YOUR_DEVICE_FCM_TOKEN", "notification": { "title": "Urgent Update", "body": "This needs your attention right away" }, "apns": { "headers": { "apns-priority": "10" // High priority for immediate delivery }, "payload": { "aps": { "sound": "default" } } } }
- Use
10for time-sensitive notifications (like alerts) - Use
5for non-urgent updates (like promotional messages)
3. Verify Your Target Token/Topic
Double-check that the to field in your REST request uses the correct FCM token for the device. It’s easy to accidentally use an outdated or incorrect token—you can fetch the current token in your app with this code:
Messaging.messaging().token { token, error in if let error = error { print("Error fetching FCM token: \(error)") } else if let token = token { print("FCM token: \(token)") } }
4. Confirm App Background Permissions
Even if APNs works with the Firebase Console, double-check these settings in Xcode:
- Go to your app’s Capabilities tab
- Enable Background Modes and check the Remote notifications box
- Ensure your app has been granted full notification permissions (users can disable background alerts in Settings, so verify that too)
5. Check Notification Delegate Setup
Make sure your AppDelegate is properly handling notifications in all states. Add these extensions if you haven’t already:
extension AppDelegate: UNUserNotificationCenterDelegate { // Handle notifications when the app is in the foreground func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.banner, .sound, .badge]) } // Handle user taps on notifications func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { // Add custom logic here (e.g., open a specific screen) completionHandler() } }
Don’t forget to set the delegate in didFinishLaunchingWithOptions:
UNUserNotificationCenter.current().delegate = self
The most common culprit here is an incorrectly structured payload—missing the notification field or not setting the APNs priority. Once you fix those, your REST API notifications should behave exactly like the ones from the Firebase Console.
内容的提问来源于stack exchange,提问作者Saeed Rahmatolahi

