Как отправить уведомление Firebase на все устройства через CURL?


85

Я пытаюсь отправить уведомление всем пользователям приложения (на Android), по сути дублируя то, что происходит, когда уведомление отправляется через консоль администратора Firebase. Вот команда CURL, с которой я начинаю:

curl --insecure --header "Авторизация: key = AIzaSyBidmyauthkeyisfineL-6NcJxj-1JUvEM" --header "Content-Type: application / json" -d "{\" notification \ ": {\" title \ ": \" note -Title \ ", \" body \ ": \" note-Body \ "}}" https://fcm.googleapis.com/fcm/send

Вот этот JSON, разобранный, чтобы вам было удобнее:

{
"notification":{
    "title":"note-Title",
    "body":"note-Body"
    }
}

Ответ, который возвращается, состоит всего из двух символов:

к

Вот оно, слово «к». (Заголовки сообщают о 400). Я подозреваю, что это связано с тем, что в моем JSON не указано «кому». Что вообще поставить на «до»? У меня темы не определены, и устройства ни на что не прописались. Тем не менее, они по-прежнему могут получать уведомления из панели администратора Firebase.

Я хочу попробовать пакет JSON «только данные» из-за удивительного ограничения обработки уведомлений Firebase, при котором, если ваше приложение находится на переднем плане, уведомление обрабатывается ВАШИМ обработчиком, но если ваше приложение находится в фоновом режиме, оно получает обрабатывается ВНУТРЕННЕЕ службой Firebase и никогда не передается обработчику уведомлений. По-видимому, это можно обойти, если вы отправите запрос на уведомление через API, но ТОЛЬКО если вы сделаете это только с данными. (Что затем нарушает возможность обработки одного и того же сообщения iOS и Android.) Замена «уведомления» на «данные» в любом из моих JSON не имеет никакого эффекта.

Хорошо, тогда я попытался найти решение здесь: сервер Firebase Java Server для отправки push-уведомления на все устройства, который, как мне кажется, говорит: «Хорошо, хотя уведомления для всех возможны через консоль администратора ... на самом деле это невозможно через API. " Обходной путь состоит в том, чтобы каждый клиент подписался на тему, а затем отправил уведомление в эту тему. Итак, сначала код в onCreate:

FirebaseMessaging.getInstance().subscribeToTopic("allDevices");

затем отправляю новый JSON:

{
"notification":{
    "title":"note-Title",
    "body":"note-Body"
    },
"to":"allDevices"
}

По крайней мере, теперь я получаю реальный ответ от сервера. Ответ JSON:

{
"multicast_id":463numbersnumbers42000,
"success":0,
"failure":1,
"canonical_ids":0,
"results":
    [
    {
    "error":"InvalidRegistration"
    }
    ]
}

И это идет с кодом HTTP 200. Хорошо ... согласно https://firebase.google.com/docs/cloud-messaging/http-server-ref код 200 с "InvalidRegistration" означает проблему с токеном регистрации. . Может быть? Потому что эта часть документации предназначена для сервера обмена сообщениями. Сервер уведомлений такой же? Не понятно. Я вижу в другом месте, что тема может занять несколько часов, прежде чем она станет активной. Похоже, что это сделало бы его бесполезным для создания новых чатов, так что это тоже кажется неправильным.

Я был очень взволнован, когда смог создать приложение с нуля, которое получало бы уведомления всего за несколько часов, хотя раньше я никогда не использовал Firebase. Похоже, ему предстоит пройти долгий путь, прежде чем он достигнет уровня, скажем, документации Stripe.com.

Итог: кто-нибудь знает, какой JSON предоставить для отправки сообщения на все устройства, на которых запущено приложение, для отражения функций консоли администратора?


Убедитесь, что ваш токен api, который вы используете, правильный. Также попробуйте отправить сообщение GCM на одно устройство и посмотрите, работает ли это. Вы можете получить InstanceId, запустив приложение в режиме отладки и поставив точку останова наFirebaseInstanceIdService
Джастин Слейд,

Я не вижу "токена api" при быстром поиске в Google на firebase.google.com/docs. Вы имеете в виду "ID токен"? или «токен аутентификации»? Или вы про мой ключ авторизации, указанный в шапке? Это один является хорошо: если я могу изменить его от того, что он есть, ответ сервера переключается на «несанкционированный» вместо сообщения об ошибке настоящее время я получаю.
Anders8 07

Похоже, что этот блог посвящен отправке сообщения на определенное устройство, а не отправке его всем пользователям приложения, как это было в оригинальном обсуждении.
Anders8 01

Прочтите этот пост для получения дополнительной информации -> developine.com/…
Developine

Ответы:


56

EDIT: похоже, что этот метод больше не поддерживается (спасибо @FernandoZamperin). Пожалуйста, взгляните на другие ответы!

Вместо подписки на тему вы можете вместо этого использовать conditionключ и отправлять сообщения экземплярам, ​​которые не входят в группу. Ваши данные могут выглядеть примерно так:

{
    "data": {
        "foo": "bar"
    },
    "condition": "!('anytopicyoudontwanttouse' in topics)"
}

См. Https://firebase.google.com/docs/cloud-messaging/send-message#send_messages_to_topics_2.


3
это лучший ответ. Его можно запустить немедленно, без необходимости обновлять приложение. отличный!
Tom Marvolo Riddle

наконец нашли это - они действительно должны сделать его более очевидным для использования
cwiesner

Это выглядит многообещающе, но действительно ли это работает? Похоже на взлом. Я попробовал это на примере проекта, и он работает. Однако я не уверен, будет ли он работать с моим приложением prod, у которого тысячи активных пользователей. Кто-нибудь пробовал с прод-приложением?
Сахил Патель

4
Я использовал этот подход довольно долго и работал отлично, сегодня по какой-то причине я отправляю уведомление в устаревший api, он возвращает мне message_id без ошибок, но устройства не получают push-уведомления, любые догадки, что будет проблема? Протестировал отправку на один токен, и он работал нормально.
Фернандо Замперин

1
@VitVeres Я отправил вопрос в службу поддержки firebase, и они мне ответили: «Ваше текущее использование выражений для разветвления push-уведомлений не поддерживается. Убедитесь, что темы, перечисленные в выражении, существуют для вашего проекта приложения.», Поэтому я думаю, мне придется реализовать темы в моих приложениях.
Фернандо Замперин,

98

Уведомления Firebase не имеют API для отправки сообщений. К счастью, он построен на основе Firebase Cloud Messaging, у которого есть именно такой API.

С помощью уведомлений Firebase и облачных сообщений вы можете отправлять так называемые нисходящие сообщения на устройства тремя способами:

  1. на определенные устройства , если вы знаете их идентификаторы
  2. в группы устройств , если вы знаете регистрационные идентификаторы групп
  3. к темам , которые являются лишь ключами, на которые устройства могут подписаться

Вы заметите, что нет возможности явно отправлять на все устройства. Вы можете создать такую ​​функциональность с каждым из них, например: подписав приложение на тему при ее запуске (например /topics/all) или сохранив список всех идентификаторов устройств, а затем отправив сообщение всем им.

Для отправки в тему у вас есть синтаксическая ошибка в вашей команде. Темы обозначены буквами, начинающимися с/topics/ . Поскольку в вашем коде этого нет, сервер интерпретируется allDevicesкак идентификатор устройства. Поскольку это недопустимый формат для токена регистрации устройства, возникает ошибка.

Из документации по отправке сообщений в топики:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "/topics/foo-bar",
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

Я попытался отправить {"to": "/ topic / allDevices", "data": {"message": "Это сообщение темы Firebase Cloud Messaging!"}} И получил тот же ответ InvalidRegistration. Я предполагаю, что это означает, что тема не актуальна. Я не вижу возможности в консоли посмотреть базу тем.
Anders8 07

7
/topics/во множественном числе
Франк ван Пуффелен 07

ухмылка О, опечатка, проклятие программиста. ;) Новый ответ: {"message_id": 5115052numbers95180}, который, безусловно, выглядит намного более удачным. Итак, похоже, что суть в том, что, хотя в консоли администратора есть мощная функциональность для доставки уведомлений через «Уведомления», НЕТ способа вызвать это из представлений API, и нужно просто преобразовать себя в использование сообщений. (Потеря планирования и отслеживания конверсий, встроенных в уведомления) Я поищу код обмена сообщениями для обработки получения. Спасибо, Фрэнк. :)
Anders8 07

1
Хм ... не совсем. Консоль уведомлений просто отправляет уведомления (см. Документацию о типах сообщений ). Единственное, что он делает, для чего у нас пока нет API, - это отправка аудитории .
Франк ван Пуффелен 07

1
то же самое и для iOS? Я пробовал то же самое, и я получаю уведомление, когда приложение
активно

73

Самый простой способ, который я придумал для отправки push-уведомления на все устройства, - это подписать их на тему «все», а затем отправить уведомление в эту тему. Скопируйте это в свой основной вид деятельности

FirebaseMessaging.getInstance().subscribeToTopic("all");

Теперь отправьте запрос как

{
   "to":"/topics/all",
   "data":
   {
      "title":"Your title",
      "message":"Your message"
      "image-url":"your_image_url"
   }
}

Это может быть неэффективный или нестандартный способ, но, как я уже упоминал выше, это самый простой. Пожалуйста, напишите, если у вас есть лучший способ отправить push-уведомление на все устройства.

Вы можете следовать этому руководству, если вы новичок в отправке push-уведомлений с помощью Firebase Cloud Messaging Tutorial - Push Notifications using FCM


Чтобы отправить сообщение на комбинацию тем, укажите условие , которое является логическим выражением, определяющим целевые темы. Например, следующее условие отправит сообщения устройствам, на которые подписаны, TopicAи либо, TopicBлибо TopicC:

{
   "data":
   {
      "title": "Your title",
      "message": "Your message"
      "image-url": "your_image_url"
   },
   "condition": "'TopicA' in topics && ('TopicB' in topics || 'TopicC' in topics)"
}

Узнайте больше об условиях и темах здесь, в документации FCM.


Это имеет смысл для меня. Но, как и вы, я не уверен, что это неэффективно. Пожалуйста, кто-нибудь может это прояснить?
JCarlosR

2
Я не думаю, что это неэффективно, это может быть единственным возможным способом отправить push-уведомление на все устройства (по крайней мере, я не смог найти другого способа),
Сайед Рафай

1
Лучший ответ! :)
wonsuc

2
Отличный ответ. Поскольку об этом нигде не упоминалось, важно знать, что вы будете получать сообщения такого типа, Serviceкоторые расширяются FirebaseMessagingServiceв #onMessageReceivedфункции. Таким образом, уведомление не отображается автоматически, вы должны позаботиться об этом самостоятельно.
обратный ответ 02

4

Один из способов сделать это - сделать так, чтобы все устройства ваших пользователей подписывались на тему. Таким образом, когда вы нацеливаете сообщение на определенную тему, все устройства получат его. Думаю, именно так это делает раздел уведомлений в консоли Firebase.


Прочтите этот пост для получения дополнительной информации -> developine.com/…
Developine

2

Я искал решение для своего push-уведомления в приложении Ionic Cordova.

Благодаря ответу Сайеда Рафая.

в app.component.ts

const options: PushOptions = {
  android: {
    topics: ['all']
  },

в файле сервера

"to" => "/topics/all",

1

Просто заставьте всех пользователей, которые входят в систему, подписаться на определенную тему, а затем отправьте уведомление по этой теме.


0

Проверьте свой список тем на консоли firebase.

  1. Перейти в консоль firebase

  2. Нажмите Grow из бокового меню

  3. Нажмите Cloud Messaging.

  4. Нажмите Отправить первое сообщение.

  5. В разделе уведомлений, введите что - то для заголовка уведомления и текст уведомления

  6. Нажмите Далее

  7. В целевом разделе нажмите Тема

  8. Нажмите на текстовое поле темы сообщения , после чего вы увидите свои темы (я не создавал тему под названием android или ios, но я вижу эти две темы.

  9. Когда вы отправляете push-уведомление, добавьте это как ваше условие.

    "condition" => "'все' в темах || 'android' в темах || 'ios' в темах",

Все тело

array(
    "notification"=>array(
        "title"=>"Test",
        "body"=>"Test Body",
    ),
    "condition"=> "'all' in topics || 'android' in topics || 'ios' in topics",
);

Если у вас есть другие темы, вы можете добавить их с помощью || (или) условие, тогда все пользователи получат ваше уведомление. Проверял и работал у меня.


-4

Вы можете отправлять уведомления на все устройства, используя "/ themes / all"

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{
  "to": "/topics/all",
  "notification":{ "title":"Notification title", "body":"Notification body", "sound":"default", "click_action":"FCM_PLUGIN_ACTIVITY", "icon":"fcm_push_icon" },
  "data": {
    "message": "This is a Firebase Cloud Messaging Topic Message!",
   }
}

Это новый функционал? Или для этого требуется, чтобы приложение подписалось на «все»?
Anders8

Это функция по умолчанию. Я не подписываюсь ни на одну тему. У меня это работает. Но я сделал регистрацию токена. "getToken"
Шива Каруппия

1
Да, вы получите идентификатор сообщения, но ничего не будет отправлено ни на одно устройство, если у вас нет темы с именем «все».
Abdalrahman Shatou

Нет, я получил уведомление на своих устройствах Android (два). вы хотите, чтобы я прикрепил свой снимок экрана ?. Я создаю свое приложение поверх ioinc.
Шива Карупиах

У меня это работает. Не знаю, почему это отклонено.
m1crdy 03
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.