Для приложения Flutter на macOS возникает ошибка ‘APNS token has not been set yet. Please ensure the APNS token is available by calling getAPNSToken()

Вопрос или проблема

Я разрабатываю приложение, которое работает на 5 платформах – android, iOS, macOS, windows и web. Сейчас я на этапе, когда мне нужно реализовать push-уведомления для этих 5 платформ. Я использую плагин firebase_messaging для push-уведомлений. Он работает на android и iOS, но не работает на macOS. Выдает ошибку [firebase_messaging/apns-token-not-set] APNS token has not been set yet. Please ensure the APNS token is available by calling getAPNSToken() при попытке получить fcm токен.

Я настроил firebase согласно этой инструкции. Даже я инициализировал плагин внимательно для всех поддерживаемых платформ.


void main() async {
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  if (kIsWeb ||
      (Platform.isAndroid ||
          Platform.isIOS ||
          Platform.isMacOS 
          )) {
    NotificationService.init(); // вызов для получения fcmToken для тестирования
  } 
 NotificationService.getFcmToken();

runApp(MultiBlocProvider(providers: [
    BlocProvider<NetworkBloc>(
        create: (_) => NetworkBloc()..add(ListenConnection())),
    BlocProvider(create: (context) => SocketCubit()),
    BlocProvider(
      create: (context) => HomeCubit(),
    ),
    BlocProvider<ProfileCubit>(create: (_) => ProfileCubit()),
  ], 
  child: const MyApp()));
}

Класс DefaultFirebaseOptions :


class DefaultFirebaseOptions {
  static FirebaseOptions get currentPlatform {
    if (kIsWeb) {
      return web;
    }
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        return android;
    case TargetPlatform.iOS:
      return ios;
    case TargetPlatform.macOS:
      return macos;
      case TargetPlatform.windows:
      //  return windows;
      throw UnsupportedError(
          'DefaultFirebaseOptions не настроены для windows - '
              'вы можете перенастроить это, запустив FlutterFire CLI снова.',
        );
      case TargetPlatform.linux:
        throw UnsupportedError(
          'DefaultFirebaseOptions не настроены для linux - '
              'вы можете перенастроить это, запустив FlutterFire CLI снова.',
        );
      default:
        throw UnsupportedError(
          'DefaultFirebaseOptions не поддерживаются для этой платформы.',
        );
    }
  }

  static const FirebaseOptions web = FirebaseOptions(
      apiKey: "AIzaSy....",
      authDomain: "...",
      projectId: "...",
      storageBucket: "...",
      messagingSenderId: "......",
      appId: "...",
      measurementId: "..."
  );

  static const FirebaseOptions android = FirebaseOptions(
    apiKey: 'AIz...',
    appId: '....',
    messagingSenderId: '....',
    projectId: '....',
    storageBucket: '....',
  );

static const FirebaseOptions ios = FirebaseOptions(
  apiKey: 'AIz....',
  appId: '....',
  messagingSenderId: '...',
  projectId: '...',
  storageBucket: '...',
);

static const FirebaseOptions macos = FirebaseOptions(
    apiKey: "AIz...",
    authDomain: "...",
    projectId: "...",
    storageBucket: "...",
    messagingSenderId: "....",
    appId: "...",
    measurementId: "....."
);
 
     
  
}

Класс NotificationService :

class NotificationService {
 static FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
 static init() async {
    await firebaseMessaging.requestPermission();
    
  }

static Future<String?> getFcmToken() async {
    try {
      String? token;
      if (kIsWeb || Platform.isAndroid || Platform.isIOS || Platform.isMacOS) {
        token = await firebaseMessaging.getToken();
      }
      // else if( Platform.isMacOS){
      //   await Future.delayed(const Duration(seconds: 3));
      //     token = await firebaseMessaging.getAPNSToken();

      // }
      else if (Platform.isWindows) {
        token = '';
      }

      debugPrint("FCM TOKEN--------------->$token");
      return token;
    } catch (e) {
      debugPrint("FCM TOken error ----------->$e");
      rethrow;
    }
  }

}

введите описание изображения здесь

Ответ или решение

Решение проблемы с получением APNS токена для приложения на macOS, использующего Flutter и Firebase

В вашем случае, когда приложение на macOS не может получить APNS токен и вызывает ошибку APNS token has not been set yet, необходимо удостовериться, что все шаги по интеграции Firebase и настройки получения токена выполнены правильно. Ниже приведены подробные рекомендации, которые помогут вам решить эту проблему.

1. Настройка проекта Firebase для macOS

Убедитесь, что ваш проект Firebase правильно настроен для работы с платформой macOS. Вам необходимо убедиться, что:

  • Вы создали приложение для macOS в консоли Firebase.
  • Скачать файл GoogleService-Info.plist и поместить его в корень вашего macOS проекта.
  • Включено использование APNs в настройках вашего приложения на сайте Firebase.

2. Включение разрешений

Перед тем как запрашивать APNS токен, необходимо запросить разрешение у пользователя на получение уведомлений. Убедитесь, что вы вызываете метод requestPermission() в init() вашего сервиса уведомлений, как указано в вашем коде. Это уже реализовано, но необходимо убедиться, что пользователь разрешает уведомления.

static init() async {
  await firebaseMessaging.requestPermission();
  // Дополнительные настройки могут быть добавлены здесь
}

3. Получение токена APNS

При работе с macOS важно правильно вызывать метод getAPNSToken(). Для получения APNS токена ожидайте некоторое время, чтобы удостовериться, что токен был установлен. Кроме того, метод getToken() для Firebase обычно возвращает токен FCM, который не соответствует APNS токену. Убедитесь, что вы явно запрашиваете токен APNS следующим образом:

if (Platform.isMacOS) {
  String? apnsToken = await firebaseMessaging.getAPNSToken();
  debugPrint("APNS TOKEN: $apnsToken");
}

4. Изменения в NotificationService

Ваш метод getFcmToken() можно изменить для более четкой обработки APNS токена. Пример ниже демонстрирует, как разделить логику получения токена для различных платформ:

static Future<String?> getFcmToken() async {
  try {
    String? token;
    if (Platform.isMacOS) {
      await Future.delayed(const Duration(seconds: 3)); // ждем, пока будет установлен APNS токен
      token = await firebaseMessaging.getAPNSToken(); // Получаем APNS токен
      debugPrint("APNS TOKEN---------------&gt;$token");
    } else {
      token = await firebaseMessaging.getToken(); // Получаем FCM токен для других платформ
    }
    debugPrint("FCM TOKEN---------------&gt;$token");
    return token;
  } catch (e) {
    debugPrint("FCM Token error -----------&gt;$e");
    rethrow;
  }
}

5. Проверьте настройки проекта

Убедитесь, что ваш проект настроен с использованием правильных версий Flutter и Firebase. Иногда проблемы могут быть вызваны несовместимыми версиями библиотек. Проверьте файл pubspec.yaml для обновления до последних стабильных версий firebase_messaging и других зависимостей.

Заключение

Чтобы успешно работать с push-уведомлениями на macOS с использованием Firebase и Flutter, следуйте указанным выше рекомендациям. Убедитесь, что все настройки выполнены точно, а также что вы обрабатываете получаемые токены корректно. Это улучшит стабильность вашего приложения и обеспечит его успешную работу на всех целевых платформах. Если после выполнения всех шагов проблема остается, рассмотрите возможность пересоздания проекта Firebase и повторной интеграции.Firebase, так как ошибки конфигурации могут возникнуть даже на самом начальном этапе.

Оцените материал
Добавить комментарий

Капча загружается...