¿Cómo se envía una notificación de Firebase a todos los dispositivos a través de CURL?


84

Estoy intentando enviar una notificación a todos los usuarios de la aplicación (en Android), esencialmente duplicando lo que sucede cuando se envía una notificación a través de la consola de administración de Firebase. Aquí está el comando CURL con el que comienzo:

curl --insecure --header "Autorización: clave = AIzaSyBidmyauthkeyisfineL-6NcJxj-1JUvEM" --header "Tipo de contenido: aplicación / json" -d "{\" notificación \ ": {\" título \ ": \" nota -Título \ ", \" cuerpo \ ": \" nota-Cuerpo \ "}}" https://fcm.googleapis.com/fcm/send

Aquí está el JSON analizado para que sea más agradable para sus ojos:

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

La respuesta que regresa son solo dos caracteres:

a

Eso es todo, la palabra "para". (Los encabezados informan un 400) Sospecho que esto tiene que ver con no tener un "para" en mi JSON. ¿Qué pondría uno por un "a"? No tengo temas definidos, y los dispositivos no se han registrado para nada. Sin embargo, aún pueden recibir notificaciones del panel de administración de Firebase.

Quiero intentar un paquete JSON de "solo datos" debido a la asombrosa limitación del procesamiento de notificaciones de Firebase por el cual si su aplicación está en primer plano, SU controlador procesa la notificación, pero si su aplicación está en segundo plano, se obtiene procesado INTERNAMENTE por el servicio de Firebase y nunca pasó a su controlador de notificaciones. Aparentemente, esto se puede solucionar si envía su solicitud de notificación a través de la API, pero SOLO si lo hace con datos únicamente. (Lo que luego rompe la capacidad de manejar iOS y Android con el mismo mensaje). Reemplazar "notificación" con "datos" en cualquiera de mis JSON no tiene ningún efecto.

Ok, entonces intenté la solución aquí: Firebase Java Server para enviar notificaciones push a todos los dispositivos, lo que me parece que dice "Ok, aunque las notificaciones para todos son posibles a través de la consola de administración ... no es realmente posible a través de la API. " La solución alternativa es que cada cliente se suscriba a un tema y luego envíe la notificación a ese tema. Entonces, primero el código en onCreate:

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

luego el nuevo JSON que envío:

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

Así que ahora estoy obteniendo una respuesta real del servidor al menos. Respuesta JSON:

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

Y eso viene con un código HTTP 200. Ok ... de acuerdo con https://firebase.google.com/docs/cloud-messaging/http-server-ref un código 200 con "InvalidRegistration" significa un problema con el token de registro . ¿Tal vez? Porque esa parte de la documentación es para el servidor de mensajería. ¿El servidor de notificaciones es el mismo? Poco claro. Veo en otros lugares que el tema puede tardar horas en activarse. Parece que eso lo haría inútil para crear nuevas salas de chat, por lo que eso también parece estar mal.

Estaba muy emocionado cuando pude codificar una aplicación desde cero que recibía notificaciones en solo unas horas cuando nunca antes había usado Firebase. Parece que le queda un largo camino por recorrer antes de alcanzar el nivel de, digamos, la documentación de Stripe.com.

En pocas palabras: ¿alguien sabe qué JSON proporcionar para enviar un mensaje a todos los dispositivos que ejecutan la aplicación para reflejar la funcionalidad de la consola de administración?


Verifique que su token de API que está utilizando sea correcto. También intente enviar el mensaje GCM a un solo dispositivo y vea si funciona. Puede obtener el ID de instancia iniciando la aplicación en depuración y poniendo un punto de interrupción en elFirebaseInstanceIdService
Justin Slade

No veo "api token" en una búsqueda rápida en Google de firebase.google.com/docs. ¿Te refieres a "token de identificación"? o "token de autenticación"? ¿O está hablando de mi clave de autorización como se proporciona en el encabezado? Ese está bien: si lo cambio de lo que es, la respuesta del servidor cambia a "no autorizado" en lugar del mensaje de error que recibo actualmente.
Anders8

Ese blog parece tratar sobre enviar un mensaje a un dispositivo en particular, no, como la discusión original, sobre enviarlo solo a todos los usuarios de la aplicación.
Anders8

Leer esta entrada de blog para más detalles -> developine.com/...
Developine

Respuestas:


56

EDITAR: Parece que este método ya no es compatible (gracias a @FernandoZamperin). ¡Eche un vistazo a las otras respuestas!

En lugar de suscribirte a un tema, puedes utilizar la conditionclave y enviar mensajes a instancias que no están en un grupo. Sus datos pueden verse así:

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

Ver https://firebase.google.com/docs/cloud-messaging/send-message#send_messages_to_topics_2


3
es la mejor respuesta. Se puede ejecutar de inmediato sin necesidad de actualizaciones de la aplicación. ¡estupendo!
Tom Marvolo Riddle

finalmente encontré ese - realmente deberían hacer que sea más obvio usarlo
cwiesner

Esto parece prometedor, pero ¿realmente funciona? Parece un truco. Lo probé en un proyecto de muestra y funciona. Sin embargo, no estoy seguro de si funcionará con mi aplicación prod, que tiene miles de usuarios activos. ¿Alguien lo ha probado con una aplicación prod?
Sahil Patel

4
Estuve usando este enfoque durante bastante tiempo y funcionaba perfectamente, hoy, por alguna razón, envío la notificación a la api heredada, me devuelve el message_id sin errores, pero los dispositivos no están recibiendo las notificaciones push, alguna conjetura cuál sería el ¿problema? Probado enviar a un solo token y funcionó normalmente.
Fernando Zamperin

1
@VitVeres Envié un problema al equipo de soporte de firebase y me respondieron: "Tu uso actual de expresiones para distribuir notificaciones push no es compatible. Asegúrate de que los temas enumerados en la expresión existan para el proyecto de tu aplicación". Supongo que tendré que implementar temas en mis aplicaciones.
Fernando Zamperin

98

Firebase Notifications no tiene una API para enviar mensajes. Afortunadamente, está construido sobre Firebase Cloud Messaging, que tiene precisamente esa API.

Con Firebase Notifications y Cloud Messaging, puedes enviar los llamados mensajes descendentes a los dispositivos de tres formas:

  1. a dispositivos específicos , si conoce sus ID de dispositivo
  2. a grupos de dispositivos , si conoce los ID de registro de los grupos
  3. a temas , que son solo claves a las que los dispositivos pueden suscribirse

Notarás que no hay forma de enviar a todos los dispositivos explícitamente. Sin embargo, puede crear dicha funcionalidad con cada uno de estos, por ejemplo: suscribiendo la aplicación a un tema cuando se inicia (por ejemplo /topics/all) o manteniendo una lista de todos los ID de dispositivos y luego enviando el mensaje a todos ellos.

Para enviar a un tema, tiene un error de sintaxis en su comando. Los temas se identifican comenzando con /topics/. Como no tiene eso en su código, el servidor lo interpreta allDevicescomo una identificación de dispositivo. Dado que es un formato no válido para un token de registro de dispositivo, genera un error.

De la documentación sobre el envío de mensajes a temas:

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!",
   }
}

Intenté enviar {"to": "/ topic / allDevices", "data": {"message": "¡Este es un mensaje de tema de Firebase Cloud Messaging!"}} Y recibí la misma respuesta de InvalidRegistration. Supongo que eso significa que el tema no es válido. No veo forma en la consola de mirar una base de datos de temas.
Anders8

7
/topics/es plural
Frank van Puffelen

sonrisa de satisfacción Oh, error tipográfico, perdición del programador. ;) La nueva respuesta es: {"message_id": 5115052numbers95180} que ciertamente parece mucho más exitosa. Entonces, parece que la conclusión es que, si bien hay una funcionalidad de poder desde la consola de administración para enviar notificaciones a través de "Notificaciones", NO hay forma de desencadenar eso desde los envíos de API, y uno debería simplemente convertirse en usar mensajes. (Perdiendo la programación y el seguimiento de conversiones integrado en las Notificaciones) Buscaré el código de mensajería para manejar la recepción. Gracias Frank. :)
Anders8

1
Uhm ... no realmente. La consola de notificaciones solo envía mensajes de notificación (consulte esta documentación sobre los tipos de mensajes ). Lo único que hace para lo que todavía no tenemos una API es enviar a las audiencias .
Frank van Puffelen

1
¿Es lo mismo para iOS también? Intenté lo mismo y recibo la notificación cuando la aplicación está activa, pero en segundo plano no funciona
vinbhai4u

72

La forma más sencilla que se me ocurrió para enviar la notificación automática a todos los dispositivos es suscribirlos a un tema "todos" y luego enviar una notificación a este tema. Copia esto en tu actividad principal

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

Ahora envíe la solicitud como

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

Esta puede ser una forma ineficiente o no estándar, pero como mencioné anteriormente, es la más fácil. Por favor publique si tiene una mejor manera de enviar una notificación de inserción a todos los dispositivos.

Puede seguir este tutorial si es nuevo en el envío de notificaciones push usando Firebase Cloud Messaging Tutorial - Push Notifications usando FCM


Para enviar un mensaje a una combinación de temas, especifique una condición , que es una expresión booleana que especifica los temas de destino. Por ejemplo, la siguiente condición enviará mensajes a los dispositivos que están suscritos TopicAy ya sea TopicBo TopicC:

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

Lea más sobre las condiciones y los temas aquí en la documentación de FCM


Tiene sentido para mí. Pero al igual que usted, no estoy seguro de que sea ineficiente. Por favor, ¿alguien puede aclararlo?
JCarlosR

2
No creo que sea ineficiente, esa podría ser la única forma posible de enviar notificaciones automáticas a todos los dispositivos (al menos no pude encontrar otra forma)
Syed Rafay

1
¡La mejor respuesta! :)
wonsuc

2
Gran respuesta. Como no se mencionó en ninguna parte, es importante saber que recibirá este tipo de mensajes en su Serviceque se extiende FirebaseMessagingServiceen la #onMessageReceivedfunción. Para que la notificación no se muestre automáticamente, debe encargarse de ella por su cuenta.
reverso

4

Una forma de hacerlo es hacer que todos los dispositivos de sus usuarios se suscriban a un tema. De esa forma, cuando oriente un mensaje a un tema específico, todos los dispositivos lo recibirán. Creo que así es como lo hace la sección de Notificaciones en la consola de Firebase.


Leer esta entrada de blog para más detalles -> developine.com/...
Developine

2

Estaba buscando una solución para la notificación de inserción de mi aplicación Ionic Cordova.

Gracias a la respuesta de Syed Rafay.

en app.component.ts

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

en el archivo del servidor

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

1

Simplemente haga que todos los usuarios que inicien sesión se suscriban a un tema específico y luego envíe una notificación a ese tema.


0

Consulta tu lista de temas en firebase console.

  1. Ir a la consola de base de fuego

  2. Haga clic en Crecer en el menú lateral

  3. Haga clic en Mensajería en la nube

  4. Haz clic en Enviar tu primer mensaje.

  5. En la sección de notificación, escriba algo para el título de la notificación y el texto de la notificación

  6. Haga clic en Siguiente.

  7. En la sección de destino, haga clic en Tema

  8. Haga clic en el cuadro de texto del tema del mensaje , luego podrá ver sus temas (no creé un tema llamado android o ios, pero puedo ver esos dos temas.

  9. Cuando envíe una notificación de inserción, agregue esto como su condición.

    "condition" => "'todos' en temas || 'android' en temas || 'ios' en temas",

Cuerpo completo

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

Si tiene más temas, puede agregarlos con || (o) condición, entonces todos los usuarios recibirán su notificación. Probado y funcionado para mí.


-4

Puedes enviar notificaciones a todos los dispositivos usando "/ topics / 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!",
   }
}

¿Es esta nueva funcionalidad? ¿O esto requiere que la aplicación se suscriba a "todos"?
Anders8

Es la funcionalidad predeterminada. No me suscribo a ningún tema. Me está funcionando. Pero hice el registro simbólico. "getToken"
Siva Karuppiah

1
Recibiría un ID de mensaje, sí, pero no se envía nada a ningún dispositivo a menos que tenga un tema llamado "todos".
Abdalrahman Shatou

No. Recibí la notificación en mis dispositivos Android (dos). quieres que adjunte mi captura de pantalla ?. Estoy construyendo mi aplicación sobre ioinc.
Siva Karuppiah

Esto funciona para mi. No sé por qué se rechaza esto.
m1crdy

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.