Чтобы отправить сообщение на несколько устройств, используйте обмен сообщениями по темам . Эта функция позволяет отправлять сообщение на несколько устройств, которые выбрали определенную тему.
В этом руководстве основное внимание уделяется отправке тематических сообщений с вашего сервера приложений с помощью Admin SDK или REST API для FCM , а также их получению и обработке в приложении Apple. На этой странице перечислены все шаги для достижения этой цели, от настройки до проверки, поэтому на ней могут быть описаны шаги, которые вы уже выполнили, если вы настроили клиентское приложение Apple для FCM или выполнили шаги по отправке первого сообщения .
Добавьте Firebase в свой проект Apple
В этом разделе описаны задачи, которые вы могли выполнить, если вы уже включили другие функции Firebase для своего приложения. В частности, для FCM вам необходимо загрузить ключ аутентификации APN и зарегистрироваться для удаленных уведомлений .
Предварительные условия
Установите следующее:
- Xcode 15.2 или новее
Убедитесь, что ваш проект соответствует этим требованиям:
- Ваш проект должен быть ориентирован на эти версии платформы или более поздние:
- iOS 13
- macOS 10.15
- ТВОС 13
- смотретьOS 7
- Ваш проект должен быть ориентирован на эти версии платформы или более поздние:
Настройте физическое устройство Apple для запуска вашего приложения и выполните следующие задачи:
- Получите ключ аутентификации Apple Push Notification для своей учетной записи Apple Developer .
- Включите push-уведомления в XCode в разделе «Приложение» > «Возможности» .
- Войдите в Firebase, используя свою учетную запись Google.
Если у вас еще нет проекта Xcode и вы просто хотите опробовать продукт Firebase, вы можете загрузить один из наших примеров быстрого запуска .
Создать проект Firebase
Прежде чем вы сможете добавить Firebase в свое приложение Apple, вам необходимо создать проект Firebase для подключения к вашему приложению. Посетите раздел «Понимание проектов Firebase», чтобы узнать больше о проектах Firebase.
Зарегистрируйте свое приложение в Firebase
Чтобы использовать Firebase в своем приложении Apple, вам необходимо зарегистрировать свое приложение в проекте Firebase. Регистрация вашего приложения часто называется «добавлением» вашего приложения в проект.
Перейдите в консоль Firebase .
В центре страницы обзора проекта щелкните значок iOS+ , чтобы запустить рабочий процесс установки.
Если вы уже добавили приложение в свой проект Firebase, нажмите «Добавить приложение», чтобы отобразить параметры платформы.
Введите идентификатор пакета вашего приложения в поле идентификатора пакета .
Идентификатор пакета однозначно идентифицирует приложение в экосистеме Apple.
Найдите идентификатор своего пакета: откройте свой проект в Xcode, выберите приложение верхнего уровня в навигаторе проекта, затем выберите вкладку «Общие» .
Значением поля «Идентификатор пакета» является идентификатор пакета (например,
com.yourcompany.yourproject
).Имейте в виду, что значение идентификатора пакета чувствительно к регистру и его нельзя изменить для этого приложения Firebase после его регистрации в вашем проекте Firebase.
(Необязательно) Введите другую информацию о приложении: псевдоним приложения и идентификатор App Store .
Псевдоним приложения : внутренний удобный идентификатор, который виден только вам в консоли Firebase .
Идентификатор App Store : используется Firebase Dynamic Links для перенаправления пользователей на вашу страницу в App Store и Google Analytics для импорта событий-конверсий в Google Ads . Если у вашего приложения еще нет идентификатора App Store, вы можете добавить его позже в настройках проекта .
Нажмите Зарегистрировать приложение .
Добавьте файл конфигурации Firebase
Нажмите «Загрузить GoogleService-Info.plist» , чтобы получить файл конфигурации платформы Firebase Apple (
GoogleService-Info.plist
).Файл конфигурации Firebase содержит уникальные, но несекретные идентификаторы вашего проекта. Чтобы узнать больше об этом файле конфигурации, посетите раздел «Понимание проектов Firebase» .
Вы можете снова загрузить файл конфигурации Firebase в любое время.
Убедитесь, что к имени файла конфигурации не добавлены дополнительные символы, например
(2)
.
Переместите файл конфигурации в корень вашего проекта Xcode. При появлении запроса выберите добавление файла конфигурации ко всем целевым объектам.
Если в вашем проекте есть несколько идентификаторов пакета, вы должны связать каждый идентификатор пакета с зарегистрированным приложением в консоли Firebase , чтобы каждое приложение могло иметь собственный файл GoogleService-Info.plist
.
Добавьте Firebase SDK в свое приложение
Используйте Swift Package Manager для установки зависимостей Firebase и управления ими.
- В Xcode, открыв проект приложения, выберите «Файл» > «Добавить пакеты» .
- При появлении запроса добавьте репозиторий Firebase SDK для платформ Apple:
- Выберите библиотеку Firebase Cloud Messaging .
- Добавьте флаг
-ObjC
в раздел «Другие флаги компоновщика» настроек сборки вашей цели. - Для оптимальной работы с Firebase Cloud Messaging мы рекомендуем включить Google Analytics в вашем проекте Firebase и добавить Firebase SDK для Google Analytics в ваше приложение. Вы можете выбрать библиотеку без коллекции IDFA или с коллекцией IDFA.
- По завершении Xcode автоматически начнет разрешать и загружать ваши зависимости в фоновом режиме.
https://github.com/firebase/firebase-ios-sdk.git
Загрузите свой ключ аутентификации APNs
Загрузите ключ аутентификации APN в Firebase. Если у вас еще нет ключа аутентификации APN, обязательно создайте его в Центре участников Apple Developer .
Внутри вашего проекта в консоли Firebase выберите значок шестеренки, выберите «Настройки проекта» , а затем выберите вкладку «Облачные сообщения» .
В разделе «Ключ аутентификации APN» в разделе «Конфигурация приложения iOS» нажмите кнопку «Загрузить» .
Перейдите в папку, в которой вы сохранили ключ, выберите его и нажмите «Открыть» . Добавьте идентификатор ключа (доступен в Центре участников Apple Developer ) и нажмите «Загрузить» .
Инициализируйте Firebase в своем приложении
Вам нужно будет добавить код инициализации Firebase в свое приложение. Импортируйте модуль Firebase и настройте общий экземпляр, как показано:
- Импортируйте модуль
FirebaseCore
в свойUIApplicationDelegate
, а также любые другие модули Firebase, которые использует ваш делегат приложения. Например, чтобы использовать Cloud Firestore и Authentication :SwiftUI
import SwiftUI import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
Быстрый
import FirebaseCore import FirebaseFirestore import FirebaseAuth // ...
Цель-C
@import FirebaseCore; @import FirebaseFirestore; @import FirebaseAuth; // ...
- Настройте общий экземпляр
FirebaseApp
в методеapplication(_:didFinishLaunchingWithOptions:)
делегата вашего приложения:SwiftUI
// Use Firebase library to configure APIs FirebaseApp.configure()
Быстрый
// Use Firebase library to configure APIs FirebaseApp.configure()
Цель-C
// Use Firebase library to configure APIs [FIRApp configure];
- Если вы используете SwiftUI, вам необходимо создать делегат приложения и прикрепить его к структуре вашего
App
черезUIApplicationDelegateAdaptor
илиNSApplicationDelegateAdaptor
. Вы также должны отключить переключение делегатов приложений. Дополнительную информацию смотрите в инструкциях SwiftUI .SwiftUI
@main struct YourApp: App { // register app delegate for Firebase setup @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate var body: some Scene { WindowGroup { NavigationView { ContentView() } } } }
Зарегистрируйтесь для удаленных уведомлений
Либо при запуске, либо в нужном месте потока приложения зарегистрируйте приложение для удаленных уведомлений. ВызовитеregisterForRemoteNotifications
, как показано:Быстрый
UNUserNotificationCenter.current().delegate = self let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization( options: authOptions, completionHandler: { _, _ in } ) application.registerForRemoteNotifications()
Цель-C
[UNUserNotificationCenter currentNotificationCenter].delegate = self; UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) { // ... }]; [application registerForRemoteNotifications];
Подписать клиентское приложение на тему
Клиентские приложения могут подписаться на любую существующую тему или создать новую тему. Когда клиентское приложение подписывается на новое имя темы (которое еще не существует для вашего проекта Firebase), в FCM создается новая тема с этим именем, и любой клиент впоследствии может подписаться на нее.
Чтобы подписаться на тему, вызовите метод подписки из основного потока вашего приложения ( FCM не является потокобезопасным). Если запрос на подписку сначала завершается неудачей, FCM автоматически повторяет попытку. В случаях, когда подписка не может быть завершена, подписка выдает ошибку, которую можно отловить в обработчике завершения, как показано:
Быстрый
Messaging.messaging().subscribe(toTopic: "weather") { error in print("Subscribed to weather topic") }
Цель-C
[[FIRMessaging messaging] subscribeToTopic:@"weather" completion:^(NSError * _Nullable error) { NSLog(@"Subscribed to weather topic"); }];
Этот вызов отправляет асинхронный запрос к серверной части FCM и подписывает клиента на данную тему. Прежде чем вызывать subscribeToTopic:topic
, убедитесь, что экземпляр клиентского приложения уже получил токен регистрации через обратный вызов didReceiveRegistrationToken
.
При каждом запуске приложения FCM проверяет, подписаны ли все запрошенные темы. Чтобы отказаться от подписки, вызовите unsubscribeFromTopic:topic
, и FCM отпишется от темы в фоновом режиме.
Получать и обрабатывать тематические сообщения
FCM доставляет тематические сообщения так же, как и другие последующие сообщения.
Реализуйте application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
как показано:
Быстрый
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async -> UIBackgroundFetchResult { // If you are receiving a notification message while your app is in the background, // this callback will not be fired till the user taps on the notification launching the application. // TODO: Handle data of notification // With swizzling disabled you must let Messaging know about the message, for Analytics // Messaging.messaging().appDidReceiveMessage(userInfo) // Print message ID. if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } // Print full message. print(userInfo) return UIBackgroundFetchResult.newData }
Цель-C
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { // If you are receiving a notification message while your app is in the background, // this callback will not be fired till the user taps on the notification launching the application. // TODO: Handle data of notification // With swizzling disabled you must let Messaging know about the message, for Analytics // [[FIRMessaging messaging] appDidReceiveMessage:userInfo]; // ... // Print full message. NSLog(@"%@", userInfo); completionHandler(UIBackgroundFetchResultNewData); }
Создание запросов на отправку
После того как вы создали тему, подписав на нее экземпляры клиентского приложения на стороне клиента или через серверный API , вы можете отправлять сообщения в тему. Если вы впервые создаете запросы на отправку для FCM , ознакомьтесь с руководством по вашей серверной среде и FCM для получения важной исходной информации и информации о настройке.
В логике отправки на серверной стороне укажите желаемое имя темы, как показано:
Node.js
// The topic name can be optionally prefixed with "/topics/".
const topic = 'highScores';
const message = {
data: {
score: '850',
time: '2:45'
},
topic: topic
};
// Send a message to devices subscribed to the provided topic.
getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
Ява
// The topic name can be optionally prefixed with "/topics/".
String topic = "highScores";
// See documentation on defining a message payload.
Message message = Message.builder()
.putData("score", "850")
.putData("time", "2:45")
.setTopic(topic)
.build();
// Send a message to the devices subscribed to the provided topic.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);
Питон
# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'
# See documentation on defining a message payload.
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
topic=topic,
)
# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
Идти
// The topic name can be optionally prefixed with "/topics/".
topic := "highScores"
// See documentation on defining a message payload.
message := &messaging.Message{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Topic: topic,
}
// Send a message to the devices subscribed to the provided topic.
response, err := client.Send(ctx, message)
if err != nil {
log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)
С#
// The topic name can be optionally prefixed with "/topics/".
var topic = "highScores";
// See documentation on defining a message payload.
var message = new Message()
{
Data = new Dictionary<string, string>()
{
{ "score", "850" },
{ "time", "2:45" },
},
Topic = topic,
};
// Send a message to the devices subscribed to the provided topic.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
ОТДЫХ
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message":{
"topic" : "foo-bar",
"notification" : {
"body" : "This is a Firebase Cloud Messaging Topic Message!",
"title" : "FCM Message"
}
}
}
команда cURL:
curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
"message": {
"topic" : "foo-bar",
"notification": {
"body": "This is a Firebase Cloud Messaging Topic Message!",
"title": "FCM Message"
}
}
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Чтобы отправить сообщение по нескольким темам, укажите условие , которое представляет собой логическое выражение, определяющее целевые темы. Например, следующее условие отправит сообщения на устройства, подписанные на TopicA
и TopicB
или TopicC
:
"'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
FCM сначала оценивает все условия в скобках, а затем оценивает выражение слева направо. В приведенном выше выражении пользователь, подписанный на какую-либо отдельную тему, не получает сообщение. Аналогично, пользователь, не подписанный на TopicA
, не получит сообщение. Эти комбинации получают его:
-
TopicA
иTopicB
-
TopicA
иTopicC
В условное выражение можно включить до пяти тем.
Чтобы отправить условие:
Node.js
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
const condition = '\'stock-GOOG\' in topics || \'industry-tech\' in topics';
// See documentation on defining a message payload.
const message = {
notification: {
title: '$FooCorp up 1.43% on the day',
body: '$FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.'
},
condition: condition
};
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
getMessaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
Ява
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
String condition = "'stock-GOOG' in topics || 'industry-tech' in topics";
// See documentation on defining a message payload.
Message message = Message.builder()
.setNotification(Notification.builder()
.setTitle("$GOOG up 1.43% on the day")
.setBody("$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.")
.build())
.setCondition(condition)
.build();
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);
Питон
# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"
# See documentation on defining a message payload.
message = messaging.Message(
notification=messaging.Notification(
title='$GOOG up 1.43% on the day',
body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
),
condition=condition,
)
# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
Идти
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
condition := "'stock-GOOG' in topics || 'industry-tech' in topics"
// See documentation on defining a message payload.
message := &messaging.Message{
Data: map[string]string{
"score": "850",
"time": "2:45",
},
Condition: condition,
}
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
response, err := client.Send(ctx, message)
if err != nil {
log.Fatalln(err)
}
// Response is a message ID string.
fmt.Println("Successfully sent message:", response)
С#
// Define a condition which will send to devices which are subscribed
// to either the Google stock or the tech industry topics.
var condition = "'stock-GOOG' in topics || 'industry-tech' in topics";
// See documentation on defining a message payload.
var message = new Message()
{
Notification = new Notification()
{
Title = "$GOOG up 1.43% on the day",
Body = "$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.",
},
Condition = condition,
};
// Send a message to devices subscribed to the combination of topics
// specified by the provided condition.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
ОТДЫХ
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message":{
"condition": "'dogs' in topics || 'cats' in topics",
"notification" : {
"body" : "This is a Firebase Cloud Messaging Topic Message!",
"title" : "FCM Message",
}
}
}
команда cURL:
curl -X POST -H "Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA" -H "Content-Type: application/json" -d '{
"notification": {
"title": "FCM Message",
"body": "This is a Firebase Cloud Messaging Topic Message!",
},
"condition": "'dogs' in topics || 'cats' in topics"
}' https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Следующие шаги
- Вы можете использовать свой сервер для подписки экземпляров клиентских приложений на темы и выполнения других задач управления. См. Управление подписками на темы на сервере .