Reputation: 119
I am trying to implement push notifications in my flutter app.
On iOS, if I call FirebaseMessaging.instance.getToken()
, I receive the error firebase_messaging/apns-token-not-set
, so I am calling
FirebaseMessaging.instance.getAPNSToken()
but it returns null
on real devices.
Works in simulator, but not on real devices
All StackOverflow threads and all GitHub issues I read say: Push notifications don't work in the iOS simulator, use a real device. But for me it's the other way round:
In the iOS iPhone 15 simulator I do receive an APNS token, but on my real device connected via Lightning cable to my Mac and on the same device using the app via Testflight, I do not receive an APNS token.
Code
I use the following code to receive the FCM token. The code is a bit messy right now because of all the debugging I am doing. I added a delay as second step in case the first getAPNSToken() returns null, because that worked for some people, but not in my case.
Future<void> initNotifications() async {
await FirebaseMessaging.instance.setAutoInitEnabled(true);
final permissionRequest = await FirebaseMessaging.instance.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (permissionRequest.authorizationStatus == AuthorizationStatus.authorized) {
String? fcmToken;
if (Platform.isIOS) {
String? apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
debugPrint("APNS Token: $apnsToken");
fcmToken = await FirebaseMessaging.instance.getToken();
debugPrint("FCM Token: $fcmToken");
} else {
debugPrint("APNS Token not available, waiting ...");
await Future<void>.delayed(
const Duration(
seconds: 3,
),
);
apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
debugPrint("APNS Token: $apnsToken");
fcmToken = await FirebaseMessaging.instance.getToken();
debugPrint("FCM Token: $fcmToken");
} else {
debugPrint("APNS Token not available, trying to get FCM token anyway ...");
try {
fcmToken = await FirebaseMessaging.instance.getToken();
} catch (err) {
debugPrint("FCM Token not available ($err)");
}
}
}
} else {
fcmToken = await FirebaseMessaging.instance.getToken();
debugPrint("FCM Token: $fcmToken");
}
} else {
debugPrint("Notifications not authorized");
}
}
The method above is called in main.dart:
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
await FireBaseNotifications().initNotifications();
Xcode
In Xcode I enabled:
- Push Notifications
- Background Modes:
- Background fetch
- Remote notifications
Firebase console
In the project settings I added two APNs certificates (development and production).
pubspec.yaml
I am using these firebase packages:
firebase_core: ^2.20.0
firebase_messaging: ^14.7.2
I have no idea why I get the APNS token in simulator but not on my real device. I don't understand what I am missing.
Upvotes: 4
Views: 6227
Reputation: 605
I know it is an edge case. But it might be helpful for some. In my case, I realized I added Push Notifications capability only under Release. So I wasn't getting any APNS token in debug mode.
This is how it was looking (select all and see if there is Release postfix):
Now you should add the capability when All is selected.
Make sure it looks like this:
Upvotes: 0
Reputation: 21
I had the very same error , however in my case I solved it by doing the following
Add the following to your AppDelegate.swift file if not added yet
override func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){
Messaging.messaging().apnsToken = deviceToken
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken:deviceToken)
So your AppDelegate.swift file should look like :
import UIKit
import Flutter
import FirebaseCore
import FirebaseMessaging
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication ,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){
Messaging.messaging().apnsToken = deviceToken
super.application(application, didRegisterForRemoteNotificationsWithDeviceToken:deviceToken)
}
}
I also had to create new certificate and generate a new Signing profile , then opened it via xcode to update signing profile
Upvotes: 0