skip to Main Content

we are enabling push notification with firebase in our Flutter app, but it’s returning this error on my real device when I want to sign in. I don’t know where is the error, and it’s happening only with IOS. Android has no problems. I have followed the official documentation, too. Xcode: 15.2, Flutter: 3.19.5

here is the error message:

FLTFirebaseMessaging: An error occurred while calling method Messaging#getToken, errorOrNil => {
    NSErrorFailingURLKey = "https://device-provisioning.googleapis.com/checkin";
    NSErrorFailingURLStringKey = "https://device-provisioning.googleapis.com/checkin";
    NSLocalizedDescription = "The request timed out.";
    "_NSURLErrorFailingURLSessionTaskErrorKey" = "LocalDataTask <9BEF5303-AEAA-4005-9A7D-D8307A35D3D5>.<1>";
    "_NSURLErrorRelatedURLSessionTaskErrorKey" =     (
        "LocalDataTask <9BEF5303-AEAA-4005-9A7D-D8307A35D3D5>.<1>"
    );
    "_kCFStreamErrorCodeKey" = "-2103";
    "_kCFStreamErrorDomainKey" = 4;
}

here is how I initialize the initFirebase code for token:

Future<void> initFirebase() async {
  String? fcmToken;
  await Firebase.initializeApp(
      options: FirebaseOptions(
          apiKey: Platform.isAndroid
              ? "AIzaSyBuRrD9IUg721orGNJzUPw_6jBqzW0qbgcw"
              : "AIzaSyDpy26KbxDkillvYaBlX_lqvmXC1XOQSpA",
          appId: Platform.isAndroid
              ? "1:199061089561:android:bc4deb3u87dd11a1af0d90"
              : '1:199061089961:ios:09e1ew1avp141a86af0d90',
          messagingSenderId: "199061680561",
          iosBundleId: "com.flutter.truck",
          storageBucket: "truck-19121.appspot.com",
          projectId: "truck-19121"));
  if (Platform.isAndroid) {
    fcmToken = await FirebaseMessaging.instance.getToken();
  } else if (Platform.isIOS) {
    fcmToken = await FirebaseMessaging.instance.getAPNSToken();
    if (fcmToken != null) {
      await Future<void>.delayed(
        const Duration(
          seconds: 5,
        ),
      );
      fcmToken = await FirebaseMessaging.instance.getAPNSToken();
    }
  }
  printColored("FCM USER TOKEN: $fcmToken", PrintedColors.red);

  // FOREGROUND MESSAGE HANDLING.
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    debugPrint(
        "NOTIFICATION FOREGROUND MODE: ${message.notification!.title} in foreground");
    debugPrint("NOTIFICATION DATA: ${message.data} in terminated");
    LocalNotificationService.localNotificationService
        .showRemoteNotification(message);
  });

  // BACkGROUND MESSAGE HANDLING
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  // FROM TERMINATED MODE

  handleMessage(RemoteMessage message) {
    debugPrint(
        "NOTIFICATION FROM TERMINATED MODE: ${message.notification!.title} in terminated");
    debugPrint("NOTIFICATION DATA: ${message.data} in terminated");
    LocalNotificationService.localNotificationService
        .showRemoteNotification(message);
  }

  RemoteMessage? remoteMessage =
      await FirebaseMessaging.instance.getInitialMessage();

  if (remoteMessage != null) {
    handleMessage(remoteMessage);
  }

  FirebaseMessaging.onMessageOpenedApp.listen(handleMessage);
}

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  LocalNotificationService.localNotificationService
      .showRemoteNotification(message);
  debugPrint(
      "NOTIFICATION BACKGROUND MODE: ${message.notification!.title} in background");
  debugPrint("NOTIFICATION DATA: ${message.data} in terminated");
}

2

Answers


  1. You need to ask for permission for iOS before requesting apnsToken

    final notificationSettings = await FirebaseMessaging.instance.requestPermission(provisional: true);
    

    And for ios also you need to request token via getToken(),
    FCM token received via getToken() is not same as apnsToken received by apnsToken(),
    You need to get apnsToken first for ios, if that is not null you need to request for fcm token via getToken() method.

    Mainly ApnsToken is apple specific token and fcm token received by getToken () is used to send Or receive notification from fcm server.

    Below is the complete code needed for FCM (Local notification for android foreground is not included in this)

    main.dart

    void main() async {
      final widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform,
      );
      await PushNotificationService().initNotifications();
    }
    

    fcm_service.dart

    final FirebaseMessaging messaging = FirebaseMessaging.instance;
    
    @pragma('vm:entry-point')
    Future<void> handleBackgroundMessage(RemoteMessage message) async {
      handleMessage(message);
    }
    
    handleMessage(RemoteMessage? message) {
      if (message == null) return;
      // can do anything here with message. Like navigating to some s reen depending upon the message
    }
    
    class PushNotificationService {
     
      Future<void> initNotifications() async {
        try {
          await messaging.requestPermission(provisional: true);
          if (Platform.isIOS) {
            final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
            if (apnsToken == null) {
              // APNS token is available, make FCM plugin API requests...
              log('apnsToken is null');
              return;
            }
          }
          final fcmToken = await messaging.getToken();
          log('device Token: $fcmToken');
          if (fcmToken != null) {
            await initPushNotifications();
           
            FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) {
             //do something on token refresh
            }).onError((err) {
               log(err.toString());
            });
          }
        } catch (e) {
          log(e.toString());
        }
      }
           
      Future initPushNotifications() async {
        await messaging.setForegroundNotificationPresentationOptions(
          alert: true,
          badge: true,
          sound: true,
        );
        FirebaseMessaging.instance.getInitialMessage().then(handleMessage);
        FirebaseMessaging.onMessageOpenedApp.listen(handleMessage);
        FirebaseMessaging.onBackgroundMessage(handleBackgroundMessage);
        FirebaseMessaging.onMessage.listen(createLocalNotification);       
    
    Login or Signup to reply.
  2. I’ve had a similar problem, with the APNS token coming back but not the device token. I raised a similar question. I’ve today resolved the issue – it was to do with the permissions not being set up for the iOS key in APIs & Services in Google Cloud Console. Full details here: https://stackoverflow.com/a/78272520/4173169

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search