What I Have:
- A Python script which sends data-only notification messages to my device/emulator using
firebase_admin.messaging.send - A Flutter mobile app which listens for the incoming messages (
FirebaseMessaging.onMessage.listenandFirebaseMessaging.onBackgroundMessage) - The data message is parsed and a push notification is shown using
flutter_local_notifications
The issue:
The notifications don't work on just iOS. Specifically, the firebase message handlers (FirebaseMessaging.onMessage.listen and FirebaseMessaging.onBackgroundMessage) don't fire for iOS when I send a notification message from my backend.
What I Tried / Things That Do Work:
- On Android, the entire process works
- APNs token prints successfully from Flutter
- On my iOS device, sending a test notification from Firebase Admin Console works, so I'm guessing APNs is setup correctly
- On my iOS device, local push notifications work when I trigger one from
main()at startup (manually usingFlutterLocalNotificationsPlugin.show) - On my iOS device, while the Flutter handlers don't fire,
didReceiveRemoteNotificationin myAppDelegate.swiftdoes fire and prints the userInfo logging statement in XCode
I have no clue how to resolve this or debug further - any ideas?
Code Snippets:
// Info.plist contains
...
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>FirebaseScreenReportingEnabled</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>remote-notification</string>
<string>fetch</string>
</array>
...
//AppDelegate.swift
import Flutter
import UIKit
import Firebase
import FirebaseMessaging
import flutter_local_notifications
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
GeneratedPluginRegistrant.register(with: registry)}
FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
}
override func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Received remote notification: \(userInfo)") // <--- THIS PRINTS CORRECTLY
// Forward the notification to Firebase Messaging
Messaging.messaging().appDidReceiveMessage(userInfo)
// Inform iOS that processing is complete
completionHandler(.newData)
}
}
# backend python script notification function
import firebase_admin
from firebase_admin import credentials
from firebase_admin import messaging
def send_push_notification(token, data):
message = messaging.Message(
token = token,
data = data,
apns=messaging.APNSConfig(
headers={"apns-priority": "5"},
payload=messaging.APNSPayload(
aps=messaging.Aps(
content_available=True
)
)
)
)
logger.info('Sending push notification: (%s)' % (token))
logger.info(data)
try:
response = messaging.send(message)
logger.info('Successfully sent message')
except Exception as e:
logger.info(f'Error sending message: {e}')
