FLTFirebaseMessaging: произошла ошибка при вызове метода Messaging#getToken

мы включаем push-уведомление с помощью Firebase в нашем приложении Flutter, но оно возвращает эту ошибку на моем реальном устройстве, когда я хочу войти в систему. Я не знаю, где ошибка, и это происходит только с IOS. У Андроида проблем нет. Я тоже следил за официальной документацией. Xcode: 15.2, Флаттер: 3.19.5

вот сообщение об ошибке:

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;
}

вот как я инициализирую код initFirebase для токена:

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");
}

292
3

Ответы:

Вам необходимо запросить разрешение для iOS, прежде чем запрашивать apnsToken.

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

А для ios вам также необходимо запросить токен через getToken(), Токен FCM, полученный через getToken(), отличается от apnsToken, полученного с помощью apnsToken(). Сначала вам необходимо получить apnsToken для ios, если оно не равно нулю, вам нужно запросить токен fcm с помощью метода getToken().

В основном ApnsToken — это токен, специфичный для Apple, а токен fcm, полученный getToken (), используется для отправки или получения уведомлений с сервера fcm.

Ниже приведен полный код, необходимый для FCM (локальное уведомление для переднего плана Android не включено в это)

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);       

У меня была аналогичная проблема: токен APNS вернулся, но не токен устройства. Я поднял аналогичный вопрос. Сегодня я решил проблему — она была связана с тем, что для ключа iOS не были настроены разрешения в API и службах в Google Cloud Console. Полная информация здесь: https://stackoverflow.com/a/78272520/4173169


Решено

решение было с установочным SDK Firebase в моем Xcode и интеграцией с консолью