1. Введение
Этот практический урок покажет вам процесс разработки многоплатформенного приложения с использованием Firebase Cloud Messaging (FCM) на Flutter. Вы напишете один из компонентов реализации приложения, а затем соберете и запустите его без проблем на трех платформах: Android, iOS и веб. Вы также узнаете, как интегрировать FCM в Flutter и как писать код для приема и отправки сообщений. Наконец, в практическом уроке будет представлена функция блоков, специфичных для платформы, в API FCM HTTP v1, которая позволяет отправлять одно сообщение с различным поведением на разных платформах.
Предварительное условие
Базовое понимание Flutter.
Что вы узнаете
- Как настроить и создать приложение Flutter.
- Как добавить зависимости FCM.
- Как отправлять отдельные сообщения FCM в ваше приложение.
- Как отправлять сообщения FCM по темам в ваше приложение.
Что вам понадобится
- Последняя стабильная версия Android Studio , настроенная с использованием плагинов Dart и Flutter.
Вы можете выполнить это задание, используя любое из следующих устройств:
- Физическое устройство Android, подключенное к вашему компьютеру.
- Эмулятор Android (см. Запуск приложений в эмуляторе Android ).
- Любой браузер на ваш выбор, например Chrome.
Для запуска практического занятия на платформе iOS вам потребуется устройство iOS, учетная запись разработчика Apple и устройство macOS с установленным Xcode.
2. Настройка Flutter
Настройте среду разработки Flutter.
Если у вас уже настроена среда разработки Flutter, пропустите этот раздел.
Для настройки среды разработки Flutter выполните следующие шаги:
- Скачайте и установите Flutter для вашей операционной системы: Установка | Flutter
- Убедитесь, что инструмент Flutter добавлен в переменную PATH.
- Настройте редактор для Flutter, как показано в разделе «Настройка редактора | Flutter». Обязательно установите плагины Flutter и Dart для вашего редактора. В оставшейся части практического занятия вы будете использовать Android Studio.
- В командной строке запустите
flutter doctor, которая просканирует вашу конфигурацию и выдаст список отсутствующих зависимостей, которые необходимо исправить. Следуйте инструкциям, чтобы исправить все важные отсутствующие зависимости. Обратите внимание, что некоторые зависимости могут быть необязательными. Например, если вы не собираетесь разрабатывать для iOS, то отсутствие зависимости CocoaPods не станет критической проблемой.
Создайте проект Flutter
- Выполните следующие команды, чтобы создать приложение Flutter, а затем перейдите в его директорию:
flutter create --org com.flutter.fcm --project-name fcmflutter fcmflutter cd fcmflutter
- В Android Studio перейдите в меню «Файл» -> «Открыть» , найдите путь к вашему Flutter-приложению и нажмите «Открыть» , чтобы открыть проект в Android Studio. Код приложения находится в файле
lib/main.dart. - На панели инструментов Android Studio нажмите стрелку вниз, чтобы выбрать устройство Android. Если поле выбора целевого устройства пустое, установите виртуальные устройства Android , браузер Chrome или симулятор iOS, если вы предпочитаете запускать приложение из веб-браузера или устройства iOS. Возможно, вам потребуется запустить устройство вручную и обновить список, чтобы найти целевое устройство.

Нажмите «Выполнить»
для запуска приложения.

Поздравляем! Вы успешно создали приложение Flutter.
3. Настройка Firebase и FlutterFire
Для разработки приложения, интегрирующегося с Firebase Cloud Messaging с помощью Flutter, вам потребуется:
- Проект Firebase.
- Рабочий интерфейс командной строки Firebase.
- Инструкция по установке FlutterFire.
- Приложение, настроенное и сгенерированное с помощью
flutterfire configure.
Создайте свой проект Firebase.
Если у вас уже есть проект Firebase, вы можете пропустить этот шаг.
- Войдите в консоль Firebase, используя свою учетную запись Google.
- Нажмите кнопку, чтобы создать новый проект, а затем введите название проекта (например,
fcm4flutter). - Нажмите «Продолжить» .
- Если появится запрос, ознакомьтесь с условиями использования Firebase и примите их, после чего нажмите «Продолжить» .
- (Необязательно) Включите помощь ИИ в консоли Firebase (в Firebase она называется "Gemini").
- Для этого практического занятия вам не понадобится Google Analytics, поэтому отключите эту опцию.
- Нажмите «Создать проект» , дождитесь завершения подготовки проекта, а затем нажмите «Продолжить» .
Поздравляем! Вы успешно создали проект Firebase.
Настройте Firebase CLI.
Если у вас уже настроен Firebase CLI, этот шаг можно пропустить.
Перейдите в справочник Firebase CLI , чтобы загрузить и установить Firebase CLI. Войдите в Firebase с помощью своей учетной записи Google, используя следующую команду:
firebase login
Настройка FlutterFire
Откройте командную строку в вашем проекте в Android Studio ( Вид -> Окна инструментов -> Терминал ) и выполните следующие команды для настройки FlutterFire:
- Установите плагин FlutterFire:
flutter pub add firebase_core
- Установите плагин FCM:
flutter pub add firebase_messaging
- Настройте интерфейс командной строки FlutterFire:
dart pub global activate flutterfire_cli
- Настройте проект Firebase в Flutter:
Заменитеflutterfire configure --PROJECT_ID
PROJECT_IDна идентификатор проекта Firebase, созданного на первом шаге. Используйте клавиши со стрелками и пробел для выбора платформ или нажмите Enter, чтобы использовать платформы по умолчанию.
В этом практическом занятии используются платформы по умолчанию (Android, iOS и веб), но вы можете выбрать только одну или две платформы. Если потребуется ввести идентификатор пакета iOS, введите com.flutter.fcm.fcmflutter или свой собственный идентификатор пакета iOS в формате [company domain name].[project name] . После завершения команды обновите страницу консоли Firebase. Вы увидите, что в проекте Firebase созданы приложения для выбранных платформ.

Эта команда создает файл firebase_options.dart в каталоге lib , который содержит все параметры, необходимые для инициализации.
Настройка облачного обмена сообщениями для iOS
- Перейдите на страницу разработчика Apple и на вкладке «Ключи» нажмите «Создать ключ» .

- Введите имя ключа и установите флажок «Службы push-уведомлений Apple (APN)» .

- Загрузите файл ключа, имеющий расширение
.p8.
- В консоли Firebase перейдите в раздел «Настройки проекта» и выберите вкладку «Облачные сообщения» .


- Загрузите файл ключа APNs для iOS-приложения на вкладке «Облачные сообщения» . Введите идентификатор ключа APNs с вкладки «Облачные сообщения» и идентификатор команды, который можно найти в центре членства Apple.

4. Подготовка FCM
Прежде чем приложение сможет получать сообщения от FCM, ему необходимо:
- Инициализация FlutterFire.
- Запросить разрешение на отправку уведомлений.
- Зарегистрируйтесь в FCM, чтобы получить регистрационный токен.
Инициализация
Для инициализации сервиса замените основную функцию ( lib/main.dart ) следующим кодом:
// core Flutter primitives
import 'package:flutter/foundation.dart';
// core FlutterFire dependency
import 'package:firebase_core/firebase_core.dart';
// generated by flutterfire configure
import 'firebase_options.dart';
// FlutterFire's Firebase Cloud Messaging plugin
import 'package:firebase_messaging/firebase_messaging.dart';
// TODO: Add stream controller
// TODO: Define the background message handler
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// TODO: Request permission
// TODO: Register with FCM
// TODO: Set up foreground message handler
// TODO: Set up background message handler
// TODO: Subscribe to a topic
runApp(MyApp());
}
Затем в Android Studio запустите Tools -> Flutter -> Flutter Pub Get , чтобы загрузить пакеты, добавленные в разделе Set up FlutterFire , и отобразите код с соответствующими настройками Intellisense в Android Studio.
Эта функция инициализирует FlutterFire для текущей платформы DefaultFirebaseOptions.currentPlatform , которая импортируется из сгенерированного файла firebase_options.dart . Обратите внимание, что initializeApp — это асинхронная функция, и ключевое слово await гарантирует завершение инициализации перед запуском приложения.
Запросить разрешение
Приложению необходимо запросить у пользователя разрешение на получение уведомлений. Метод requestPermission предоставляемый функцией firebase_messaging отображает диалоговое окно или всплывающее окно, предлагающее пользователю разрешить или отклонить разрешение.
Сначала скопируйте этот код в основную функцию под комментарием TODO: Request permission . Возвращаемые settings покажут, предоставил ли пользователь разрешение.
final messaging = FirebaseMessaging.instance;
final settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
if (kDebugMode) {
print('Permission granted: ${settings.authorizationStatus}');
}
Далее на панели инструментов Android Studio выберите Chrome (web) в поле выбора целевого объекта, а затем снова запустите приложение.

Затем открывается вкладка Chrome с всплывающим окном, запрашивающим разрешение. Если вы нажмете Allow , в консоли Android Studio появится запись: Permission granted: AuthorizationStatus.authorized . После того, как вы разрешите или заблокируете запрос на разрешение, ваш ответ будет сохранен вместе с вашим приложением в браузере, и всплывающее окно больше не появится. Обратите внимание, что при повторном запуске веб-приложения в Android Studio вам может быть снова предложено предоставить разрешение.

Регистрация
Скопируйте этот код в основную функцию ниже комментария TODO: Register with FCM , чтобы зарегистрироваться в FCM. Вызов getToken возвращает токен регистрации, который может использоваться сервером приложений или доверенной серверной средой для отправки сообщений пользователям.
// It requests a registration token for sending messages to users from your App server or other trusted server environment.
String? token = await messaging.getToken();
if (kDebugMode) {
print('Registration Token=$token');
}
На панели инструментов Android Studio выберите устройство Android и запустите приложение. В консоли Android Studio регистрационный токен будет выведен следующим образом:
I/flutter ( 3717): Permission granted: AuthorizationStatus.authorized I/flutter ( 3717): Registration Token=dch. . . D2P:APA9. . .kbb4
Скопируйте его в текстовый редактор, так как вы будете использовать его для отправки сообщений позже.
uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:firebase_messaging]
Дополнительные шаги для получения сообщений через веб-браузер.
Веб-приложениям требуются два дополнительных шага для получения регистрационного токена и прослушивания входящих сообщений. Веб-приложениям необходимо передать ключ VAPID в функцию getToken для авторизации запросов на отправку сообщений поддерживаемым веб-сервисам push-уведомлений.
Сначала откройте вкладку «Cloud Messaging» проекта Firebase в консоли Firebase, прокрутите вниз до раздела «Веб-конфигурация» , чтобы найти существующую пару ключей, или сгенерируйте новую пару ключей. Нажмите на выделенную кнопку, чтобы скопировать ключ и использовать его в качестве vapidKey.

Далее замените регистрационный код в разделе «Регистрация» этим кодом, а затем обновите значение vapidKey:
// TODO: replace with your own VAPID key
const vapidKey = "<YOUR_PUBLIC_VAPID_KEY_HERE>";
// use the registration token to send messages to users from your trusted server environment
String? token;
if (DefaultFirebaseOptions.currentPlatform == DefaultFirebaseOptions.web) {
token = await messaging.getToken(
vapidKey: vapidKey,
);
} else {
token = await messaging.getToken();
}
if (kDebugMode) {
print('Registration Token=$token');
}
Затем создайте файл firebase-messaging-sw.js в корневом каталоге вашего проекта, в папке web/ . Скопируйте следующий код в firebase-messaging-sw.js , чтобы веб-приложение могло получать события onMessage . Дополнительную информацию см. в разделе «Настройка параметров уведомлений в сервис-воркере» .
importScripts("https://www.gstatic.com/firebasejs/9.6.10/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/9.6.10/firebase-messaging-compat.js");
// todo Copy/paste firebaseConfig from Firebase Console
const firebaseConfig = {
apiKey: "...",
authDomain: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
// todo Set up background message handler
После этого в разделе «Настройки проекта» -> вкладка «Общие» прокрутите вниз и найдите раздел «Веб-приложение» , скопируйте раздел кода firebaseConfig и вставьте его в файл firebase-messaging-sw.js . 
Наконец, на панели инструментов Android Studio выберите Chrome (web) в селекторе целей и запустите приложение. В консоли Android Studio регистрационный токен будет выведен следующим образом:
Debug service listening on ws://127.0.0.1:61538/BLQQ3Fg-h7I=/ws Permission granted: AuthorizationStatus.authorized Registration Token=fH. . .ue:APA91. . .qwt3chpv
Скопируйте регистрационный токен в текстовый редактор, чтобы использовать его для отправки сообщений в дальнейшем.
Дополнительные шаги для получения сообщений на iOS
Для получения сообщений от FCM на устройствах iOS необходимо включить push-уведомления и фоновый режим в Xcode:
- В Android Studio щелкните папку
iosв дереве файлов проекта, а затем выберите Инструменты -> Flutter -> Открыть модуль iOS в Xcode .
- После запуска Xcode включите push-уведомления и фоновый режим на вкладке «Подписание и возможности» для целевого проекта. Дополнительную информацию см. в разделе «Настройка приложения» .
- На панели инструментов Android Studio выберите устройство iOS в поле выбора цели и запустите приложение. После предоставления разрешения на уведомления в консоли Android Studio будет выведен токен регистрации.

Поздравляем, ваше приложение успешно зарегистрировано в FCM. Теперь вы готовы получать сообщения, как описано в следующем разделе.
5. Получение сообщений от FCM.
Настройка обработчиков сообщений
Приложение должно обрабатывать события onMessage , когда сообщения поступают, пока приложение находится в режиме переднего плана, и события onBackgroundMessage когда приложение находится в фоновом режиме.
Обработчик сообщений переднего плана
Сначала добавьте контроллер потока после комментария TODO: Add stream controller в файл main.dart , чтобы передавать сообщения из обработчика событий в пользовательский интерфейс.
import 'package:rxdart/rxdart.dart';
// used to pass messages from event handler to the UI
final _messageStreamController = BehaviorSubject<RemoteMessage>();
Чтобы добавить зависимость rxdart, выполните следующую команду из каталога проекта:
flutter pub add rxdart
Далее, в Android Studio запустите Tools -> Flutter -> Flutter Pub Get , чтобы загрузить пакет rxdart.dart и отобразить код с соответствующими настройками Intellisense в Android Studio.
Затем добавьте обработчик событий для прослушивания сообщений переднего плана после комментария TODO: Set up foreground message handler . Он выводит логи и публикует сообщение в контроллер потока.
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (kDebugMode) {
print('Handling a foreground message: ${message.messageId}');
print('Message data: ${message.data}');
print('Message notification: ${message.notification?.title}');
print('Message notification: ${message.notification?.body}');
}
_messageStreamController.sink.add(message);
});
После этого замените исходный виджет State, расположенный в конце файла main.dart, следующим кодом, который добавляет подписчика в контроллер потока в виджете State и отображает последнее сообщение в виджете.
class _MyHomePageState extends State<MyHomePage> {
String _lastMessage = "";
_MyHomePageState() {
_messageStreamController.listen((message) {
setState(() {
if (message.notification != null) {
_lastMessage = 'Received a notification message:'
'\nTitle=${message.notification?.title},'
'\nBody=${message.notification?.body},'
'\nData=${message.data}';
} else {
_lastMessage = 'Received a data message: ${message.data}';
}
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Last message from Firebase Messaging:',
style: Theme.of(context).textTheme.titleLarge),
Text(_lastMessage, style: Theme.of(context).textTheme.bodyLarge),
],
),
),
);
}
}
Фоновый обработчик сообщений для Android/iOS
Обработка сообщений осуществляется обработчиком onBackgroundMessage пока приложение находится в фоновом режиме. Обработчик должен быть функцией верхнего уровня. Обновление пользовательского интерфейса может происходить при выводе приложения на передний план путем обработки сообщений (см. раздел «Обработка взаимодействий ») или синхронизации с сервером приложения.
Создайте функцию-обработчик после комментария TODO: Define the background message handler вне основной функции и вызовите его в основной функции после комментария TODO: Set up background message handler .
// TODO: Define the background message handler
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
if (kDebugMode) {
print("Handling a background message: ${message.messageId}");
print('Message data: ${message.data}');
print('Message notification: ${message.notification?.title}');
print('Message notification: ${message.notification?.body}');
}
}
void main() {
...
// TODO: Set up background message handler
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
Фоновый обработчик сообщений для веб-приложений
Начиная с версии FlutterFire firebase_messaging 11.2.8, обработка фоновых сообщений на веб-платформах требует иного подхода. Поэтому необходимо добавить отдельный обработчик сообщений в сервис-воркер web/firebase-messaging-sw.js .
messaging.onBackgroundMessage((message) => {
console.log("onBackgroundMessage", message);
});
Настройте сервер приложений.
- Клонируйте репозиторий с серверным кодом
https://github.com/FirebaseExtended/firebase_fcm_flutter/tree/main/serverи откройте его в Android Studio как новый проект. Сервер представляет собой Java-проект на основе Gradle с зависимостью от SDK firebase-admin , который обеспечивает функциональность отправки сообщений FCM. - Создайте учетную запись службы Firebase, которая позволит Firebase Admin SDK авторизовывать вызовы к API FCM. Откройте настройки проекта в консоли Firebase и выберите вкладку « Учетные записи служб» . Выберите «Java» и нажмите
Generate new private keyчтобы загрузить фрагмент конфигурации.
- Переименуйте файл в
service-account.jsonи скопируйте его в папкуsrc/main/resourcesсерверного проекта.
Отправить тестовое сообщение
В файле FcmSender.java sendMessageToFcmRegistrationToken формирует уведомление с полезной нагрузкой данных. Токен регистрации указывает на экземпляр приложения, которому отправляется сообщение.
private static void sendMessageToFcmRegistrationToken() throws Exception {
String registrationToken = "REPLACE_WITH_FCM_REGISTRATION_TOKEN";
Message message =
Message.builder()
.putData("FCM", "https://firebase.google.com/docs/cloud-messaging")
.putData("flutter", "https://flutter.dev/")
.setNotification(
Notification.builder()
.setTitle("Try this new app")
.setBody("Learn how FCM works with Flutter")
.build())
.setToken(registrationToken)
.build();
FirebaseMessaging.getInstance().send(message);
System.out.println("Message to FCM Registration Token sent successfully!!");
}
- Скопируйте токен регистрации Android из раздела «Регистрация» и вставьте его в значение переменной
registrationToken. - Нажмите «Выполнить»
запустить основную функцию и отправить сообщение пользователю через FCM. 
Когда приложение Android находится в фоновом режиме, сообщение отображается в панели уведомлений.

Когда приложение Android находится на переднем плане, в консоли Android Studio вы увидите сообщение: «Обработка сообщения переднего плана». Содержимое сообщения также отображается в пользовательском интерфейсе, поскольку пользовательский интерфейс подписан на контроллер потока для получения новых сообщений.

Если вы вставите регистрационный токен и отправите сообщение с сервера приложений или другого доверенного сервера, вы увидите аналогичное поведение:
- Когда веб-приложение находится в фоновом режиме (например, когда оно скрыто другим окном или активна другая вкладка), вы увидите веб-уведомление.

- Когда веб-приложение находится на переднем плане, вы можете просмотреть журнал в консоли Chrome, щелкнув правой кнопкой мыши по веб-странице и выбрав
Inspect. Содержимое сообщений также отображается в пользовательском интерфейсе.
6. Отправьте сообщение с темой.
Функция переопределения платформы в API FCM HTTP v1 позволяет отправлять запросы на отправку сообщений с различным поведением на разных платформах. Один из вариантов использования этой функции — отображение различного содержимого уведомлений в зависимости от платформы. Эта функция наиболее эффективно используется при отправке сообщений по темам на несколько устройств (которые могут охватывать несколько платформ). В этом разделе описаны шаги по настройке вашего приложения для получения сообщений по темам, адаптированных для каждой платформы.
Подписаться на тему от клиента
Чтобы подписаться на тему, скопируйте этот код в основную функцию ниже комментария TODO: Subscribe to a topic :
// subscribe to a topic.
const topic = 'app_promotion';
await messaging.subscribeToTopic(topic);
[Необязательно] Подписаться на тему с веб-сервера
Вы можете пропустить этот раздел, если не занимаетесь разработкой на веб-платформе.
В настоящее время FCM JS SDK не поддерживает подписку на темы на стороне клиента. Вместо этого вы можете подписаться, используя API управления темами на стороне сервера из Admin SDK. Этот код в файле FcmSubscriptionManager.java демонстрирует подписку на темы на стороне сервера с помощью Java Admin SDK. Перед запуском обязательно добавьте свой регистрационный токен FCM:
private static void subscribeFcmRegistrationTokensToTopic() throws Exception {
List<String> registrationTokens =
Arrays.asList(
"REPLACE_WITH_FCM_REGISTRATION_TOKEN"); // TODO: add FCM Registration Tokens to
// subscribe
String topicName = "app_promotion";
TopicManagementResponse response = FirebaseMessaging.getInstance().subscribeToTopic(registrationTokens, topicName);
System.out.printf("Num tokens successfully subscribed %d", response.getSuccessCount());
}
Откройте сервер приложений и нажмите «Запустить».
Для запуска основной функции в файле FcmSubscriptionManager.java :

Отправить сообщение с настройками платформы в заданную тему.
Теперь вы готовы отправить сообщение с переопределением платформы темы. В следующем фрагменте кода:
- Вы формируете запрос на отправку, используя базовое сообщение и заголовок "
A new app is available". - Это сообщение генерирует уведомление с заголовком «
A new app is available» на платформах iOS и веб-версии. - Это сообщение генерирует уведомление с заголовком «
A new Android app is available» на устройствах Android.
private static void sendMessageToFcmTopic() throws Exception {
String topicName = "app_promotion";
Message message =
Message.builder()
.setNotification(
Notification.builder()
.setTitle("A new app is available")
.setBody("Check out our latest app in the app store.")
.build())
.setAndroidConfig(
AndroidConfig.builder()
.setNotification(
AndroidNotification.builder()
.setTitle("A new Android app is available")
.setBody("Our latest app is available on Google Play store")
.build())
.build())
.setTopic("app_promotion")
.build();
FirebaseMessaging.getInstance().send(message);
System.out.println("Message to topic sent successfully!!");
}
В основной функции файла FcmSender.java раскомментируйте строку sendMessageToFcmTopic(); . Нажмите « Выполнить».
отправить сообщение по теме.
7. Резюме и дальнейшие действия
В заключение, вы изучили разработку многоплатформенных приложений с использованием Flutter и FCM, включая настройку среды, интеграцию зависимостей, а также прием и отправку сообщений. Для более глубокого изучения ознакомьтесь со следующими материалами:
Кодлабс
- Чтобы узнать больше о том, как Flutter взаимодействует с другими продуктами Firebase, включая аутентификацию пользователей и синхронизацию данных, см. раздел «Знакомство с Firebase для Flutter» .
- Чтобы узнать больше о FCM, включая внутриприложениевые сообщения и темы: Используйте FCM и FIAM для отправки сообщений пользователям и Ваше первое многоадресное push-сообщение с использованием тем FCM