Google Cloud Messaging. Parte I: Introducción

The Google Cloud Messaging (GCM) guide can be found here and is available in English, therefore I am writing these related posts in Spanish.

La documentación oficial podemos verla aquí y se encuentra disponible en inglés, por lo que he decidido escribir esta serie de posts en español.

Esta es la parte I de un conjunto de entradas sobre Google Cloud Messaging (GCM).

Google Cloud Messaging (GCM) para Android es un servicio gratuito que nos permite enviar información desde nuestro servidor a un dispositivo Android. El servicio GCM controla todo lo relacionado con el almacenamiento en cola de los mensajes y su entrega a las aplicaciones.

Características básicas

  • Para que una aplicación reciba mensajes, no es necesario que ésta se encuentre ejecutándose, sino que el sistema la despertará cuando el mensaje llegue.
  • GCM pasa la información recibida directamente a la aplicación, la cual tiene control total sobre ella.
  • Requiere dispositivos con Android 2.2 o superior que tengan instalada la aplicación de Google Play Store o un emulador con Google APIs.
  • Hace uso de una conexión existente a los servicios de Google. Es necesario que los usuarios tengan configurada su cuenta de Google en el dispositivo. Esta cuenta de Google no es un requisito para los dispositivos con Android 4.0.4 o superior.

Componentes que intervienen

Dispositivo móvil
Servidores GCM
Servidor de terceros

Proceso

A continuación se muestran los pasos necesarios para que finalmente un mensaje pueda llegar a un dispositivo móvil Android.

  1. La aplicación se registra en el dispositivo móvil para recibir mensajes. Se realiza lanzando el Intent de registro “com.google.android.c2dm.intent.REGISTER“, que incluye el Sender ID y el Application ID.
  2. Si el registro ha terminado correctamente, el servidor GCM lanza un Intent “com.google.android.c2dm.intent.REGISTRATION” para devolver el Registration ID.
  3. La aplicación envía el Registration ID al servidor de terceros (nuestro servidor) para que sea guardado.
  4. Nuestro servidor ya puede enviar un mensaje para que sea recibido por el dispositivo. El servidor envía el mensaje a los servidores GCM, donde es puesto en cola.
  5. Google envía el mensaje al dispositivo cuando se encuentre accesible.
  6. El dispositivo lanza el mensaje a la aplicación especificada mediante un Intent “com.google.android.c2dm.intent.RECEIVE“, y ésta procesa el mensaje sin necesidad de que estuviera ejecutándose previamente.

Proceso GCM

Credenciales

En el proceso visto anteriormente han aparecido varios identificadores.

  • Sender ID. Se usa en el proceso de registro para identificar una aplicación Android a la cual se le permiten enviar mensajes al dispositivo. Se obtiene desde la página de Google de APIs Console.
  • Application ID. Identificador de la aplicación que se está registrando para recibir mensajes. Se trata del nombre del paquete de la aplicación indicado en el archivo manifest.
  • Registration ID. Identificador enviado por los servidores GCM a la aplicación como respuesta a una solicitud de registro. Este identificador debe ser enviado a nuestro servidor para identificar cada dispositivo que se ha registrado para recibir mensajes. Está asociado a una aplicación concreta existente en un dispositivo concreto.
  • Sender Auth Token. Clave que debe almacenar tu servidor para poder acceder a los servicios de Google.
Share Button

48 Comments

  1. Hola Belen, que buen post

    Tengo una pregunta, al dar click envio el intent y abro el screen que necesito, pero si envio 3 notificaciones me sobreescribe y en la barra solo muestra la ultima.

    Que puedo hacer para que en la barra pueda mostrar una cola de notificaciones?

    Gracias

    1. Si las notificaciones se están sobreescribiendo es porque estás usando el mismo ID para todas ellas. Si usas el mismo ID, el sistema entiende que es la misma notificación y lo que hace es actualizarla. Para evitar esto, crea las notificaciones usando IDs diferentes. El ID de la notificación es el que pasas en el método notify al NotificationManager.

  2. Buenas Belén,
    enhorabuena por esta publicación y muchas gracias por compartir estos conocimientos.

    Tengo una duda, me llega una notificacion con mi app en background y me aparece en la barra de estado del movil dicha notificacion, al deslizar la pantalla y pulsar sobre la notificación me abre mi app, pero como puedo eliminar la notificacion de la barra de estado del movil?

    Muchas gracias por todo.

    1. Muchas gracias por tu comentario. Para que la notificación desaparezca de la barra cuando el usuario la pulsa, puedes activar la cancelación automática de la notificación. Para hacer esto, cuando creas la notificación, añade la siguiente llamada:
      setAutoCancel() .

  3. hola belen felicidades por el articulo ,no estoy seguro si me servirá GCM soy nuevo en esto ,lo que yo quiero hacer es poder mandar algún dato desde mi computadora al servidor y que el servidor lo mande a mi celular o si tienes alguna recomendación te lo agradecería mucho =)

    1. Muchas gracias por tu comentario. La solución dependerá de cuándo quieras recibir el mensaje en el dispositivo móvil. Si quieres que lo reciba en el momento que se ha enviado desde el ordenador, entonces sí, podría aplicarse GCM. Si no tiene por qué ser inmediato, entonces puedes prescindir de GCM.

  4. Hola,
    Hay alguna forma de automatizar los envíos de las notificaciones push? es decir, por ejemplo mi App recibe un campo fecha que introduce el usuario (ej 17/06/2015) y de allí calcula otra fechas para lanzar notificaciones push (1º el día 19/06/2015, 2º el día 25/08/2015…..).Ayudarme por favor !!
    Gracias.

    1. Si conoces el momento exacto de la notificación, entonces no tienes que usar Google Cloud Messaging. Simplemente tienes que programar una notificación desde la propia app.

      1. Buenas,
        Sí, las fechas las puedo calcular dentro del código,pero el problema es que son fecha de vacunas de bebes y si en el futuro por ejemplo se eliminara alguna de ellas…! seria un problema, por eso quiero hacerlo desde un servidor externo.

        1. Entonces tu app puede consultar periódicamente con el servidor si las fechas han cambiado, por lo que igualmente no necesitarías Google Cloud Messaging. Es sólo que sería más sencillo, ya que es innecesario hacer toda la implementación de GCM. Pero ya es tu decisión de cómo quieras hacerlo.

          1. Po sí, también es una solución!,esto se haría con una “Class Service ” por ejemplo!?, que funcione en segundo plano?!

          2. Ya depende de la frecuencia con la que cambien. Se puede comprobar simplemente cada vez que se inicie la aplicación.

  5. Hola Belen, gracias por darte el tiempo de explicar GCM, a pesar de lo clara que ha sido tu explicacion no he podido hacerlo andar, he creado una aplicacion usando intel xdk y he agregado lo necesario para que la aplicacion escriba su registrationID en mi bbdd, ahora trato de generar un push utilizando un codigo php, pero este no me funciona, me podrias ayudar? puedo enviarte el codigo por correo, gracias.

    1. Te puedo ayudar con preguntas más concretas, pero eres tú el que debe investigar el motivo exacto de por qué no te funciona. Si el problema está en tu código PHP, poco voy a poder ayudar con eso, lo siento.

  6. Hola Belen,queria preguntarte si sabes como habilitar el modulo de AppEngine (Google cloud Module) en android studio, estaba buscando por la red y no ponen nada de eso, yo cuando quiero crear un modulo(file..-> new module) no me sale Google cloud Module! tienes alguna idea de como se puede conseguir?
    Gracias.

      1. Hola Belén, primero gracias por contestarme, la versión que estoy usando es la ultima (1.2.1.1)ya que acabo de actualizar el Android Studio…pero no me sale como modulo! no se porque ,estaba viendo en la documentación de Android y no hay otro paso previo al crearlo directamente en el proyecto.
        Gracias.

        1. Intenta crear un nuevo proyecto lo más básico y estándar posible. Comprueba entonces si te aparece. Quizá tenga algo que ver con el tipo de proyecto que estás usando. Como ya te dije, yo lo he comprobado y sí me aparece sin hacer nada más.

  7. Hola Belén, te quería hacer una consulta sobre como se debe manejar el caso en que nuestro servidor se encuentre caído cuando el dispositivo intenta enviarnos el registration ID.

    Saludos, Diego.-

    1. Hola, una opción es que cuando se inicia la aplicación, una vez se obtiene el ID, se envíe siempre al servidor. Es probable que al inicio, la app se comunique con tu servidor para comprobar usuario/estado o lo que sea. De esta forma, si el servidor está caído, la próxima vez que se ejecute la app, lo intentará de nuevo. Otra solución es poner un temporizador junto con un número de reintentos cuando una conexión con el servidor falla.

  8. Hola, muy interesante el blog, aunque se ha quedado un poco desactualizado pero me ha servido mucho para entender el GCM, y quería consultarte una cosita!, yo estoy nuevo en Android y estoy haciendo una pequeña aplicación y me gustaría implementar un método que se ejecute sin necesidad de que este la aplicación abierta y que consulte un campo de fechas en la base de datos interna que tengo en el proyecto y mande notificaciones al usuario(por ejemplo cumpleaños ,citas …) necesitaría implementar GCM? gracias.
    Saludos.

    1. Hola, muchas gracias por tu comentario. Sí, ha quedado totalmente desactualizado pero el concepto es el mismo. Respecto a lo que me comentas, si la comunicación tiene que ser iniciada por el servidor entonces sí tendrías que usar GCM. En otro caso, no sería necesario. Si las fechas de las notificaciones son fijas, es decir, sabes el momento exacto en el que necesitas la notificación, se puede programar la notificación desde la app sin necesidad de usar GCM.

      1. Si, son fechas fijas,o sea, cumpleaños fechas de vacuncas para bebes etc..,pero las notificaciones pueden lanzarse sin que este la app abierta (en uso por el usuario)?!!.,gracias y disculpa si es mucho preguntar :D.
        Un saludo.

  9. Hola Belén,

    Sigo sin comprender… si tengo un mensaje de 10Kb que necesito enviar desde mi aplicación Android a un servidor tercero (Tomcat) a través de GCM. Cómo puedo subir el mensaje de 10Kb a GCM teniendo en cuenta que existe una restricción de 4Kb… lo que yo hago es partir los mensajes cada 4Kb les asigno un identificador en común, los envío a GCM y cuando recibo un mensaje en el servidor (Tomcat) con el mismo identificador los concateno.

    Mi pregunta es: hay alguna forma de enviar el mensaje de 10Kb sin tener que realizar esa concatenación en el servidor (Tomcat) y sin tener que partir el mensaje cada 4Kb para que GCM pueda recibirlo debido a su restricción?

    Saludos.

    1. La intención de GCM no es en absoluto enviar mensajes desde la app Android a un servidor. Para eso usas una conexión HTTP normal y corriente. GCM es para enviar mensajes servidor -> app.

    1. Simplemente el servidor manda un mensaje GCM a la app con ID de mensaje comunicándole algo así como “oye, tienes información disponible”. La app recibe el mensaje por GCM y entonces conecta con el servidor “Tengo un mensaje con este ID, mándame la información”. El servidor responde con la información completa.

  10. Hola Belén

    Debido a que el servidor de GCM tiene una restricción de 4K para pasar mensajes, lo que hago es partir los mensajes desde la aplicación Andriod, es decir, si tengo un mensaje que pesa 16K lo que hago es partir el mensaje en 4 mensajes que pesen 4K y envío 4 mensajes a GCM;

    Mi pregunta es: algunas veces pasan todos los mensajes, es decir, pasa 4/4 pero algunas veces pasan 2/4 ó 3/4. Conoces alguna forma de garantizar el paso de las 4 mensajes desde el dispositivo hacia GCM?? Tal vez un parámetro adicional en la estructura del mensaje que se envía al GCM??

    1. Hola, no es buena práctica que se manden varios mensajes por querer pasar más de 4k a la app. Eso rompe la intención de GCM y de hecho, en la documentación se comenta. La práctica correcta y la cual solucionaría tu problema, es que cuando la app reciba un mensaje, se conecte al servidor y le pregunte. Entonces el servidor le puede enviar toda la información, sea del tamaño que sea y por supuesto, completa.

  11. Hola otra vez yo :$ Tengo una pregunta sobre este tema, eh estado trabajando en una app para aprender sobre como funciona este servicio de google y hasta el momento me funcionado bien pero…. cuando instalo la app en diferentes dispositivos siempreme da el mismo “registration id” se cual sea el dispositivo esto es normal? o me debería de dar una clave diferente por dispositivo? Saludos y gracias por la respuesta.

    1. Hola, el registrationID debe ser diferente en cada dispositivo. Cada registrationID identifica la app en un dispositivo concreto de forma que los servidores GCM puedan enviar notificaciones a uno concreto.

  12. Pregunta.

    Cada vez que se inicia la aplicación se tiene que registrar al servicio de google? o con solo registrarlo una vez y guardar el id en base de datos es mas que suficiente?

    Saludos y gracias por la respuesta.

    1. Si la aplicación ya está registrada, no hace falta volver a hacerlo cada vez. Para crear una aplicación a prueba de errores y cambios, mi recomendación es que el ID se compruebe cada vez que se inicie la aplicación, comprobar no quiere decir registrar. De esta forma te aseguras que no ha cambiado y que se mantiene actualizado en el servidor.

  13. Disculpa me olvidaba tambien mi aplicacion debe mandar datos a la BD de mi aplicacion web y la aplicacion web tambien enviar datos formato json. mi pregunta es si estaría bien usar este servicio GCM -??

    si podrías darme unas pautas de cómo hacer te lo agradecería mucho.

    Gracias man

    1. Como te comentaba, para que la aplicación envíe datos al servidor y al contrario, no necesitas usar GCM, tan sólo una comunicación entre ambos a través de un servicio web por ej.

  14. Hola Felicitaciones y gracias por compartir interesante!!

    Una consulta estoy iniciando con android y estoy haciendo una aplicacion móvil que se comunique con una pagina web, donde yo en la pagina le ponga la ubicacion en un mapa y este se refle en el android mi pregunta es si estaría bien usar este servicio GCM -??

    si podrías darme unas pautas de cómo hacer te lo agradecería mucho.
    Gracias man

    1. Hola, GCM está pensado para enviar notificaciones desde el servidor a la aplicación aun cuando ésta no está en ejecución. Lo que comentas y entiendo, la aplicación de Android estaría en primer plano reflejando los cambios introducidos en la web. En este caso no necesitas GCM para nada, simplemente tienes que crear un servicio web.

  15. Hola Muy buen articulo, felicitaciones y esto es lo que ayuda a la gente de todas las comunidades del mundo a colaborarsen cada dia mas y crecer. Tienes por favor algun ejemplo que podamos bajar para probar? me la podrias enviar a este mail por favor? omejiasq@gmail.com

  16. Hola muy bueno tu artículo, quiero aprovechar para hacerte unas preguntas (soy nuevo en esto)
    1 – Cuántas notificaciones se pueden enviar por día?
    2 – Hay un límite diario en la cantidad de usuarios que pueden recibir estas notificaciones?
    Gracias por la ayuda.
    Saludos.

  17. hola muy buenos tus artículos y gracias por compartirlos …me gustaria saber si con GCM se pueden desarrollar aplicaciones de mensajeria como Line o whatsapp por mencionar algunos . De todas formas gracias.

    1. Hola, sí, usando GCM se podría implementar aplicaciones de mensajería. El servidor de mensajes avisaría a los dispositivos asociados a un usuario de que hay nuevos mensajes. Sería necesario desarrollar un gran control de los mensajes que han llegado correctamente para evitar que lleguen duplicados o que otros se pierdan.

  18. Hola, te felicito por tu articulo es muy interesante e ilustrativo, de otro lado queria saber si es posible conectar 2 dispositivos android via tcp/ip sin tener que pasar por el GCM ?

    Saludos cordiales

    1. Muchas gracias. GCM se usa para enviar notificaciones desde un servidor a un dispositivo android, realmente no conecta 2 dispositivos entre sí. Para conectar 2 dispositivos vía tcp/ip, ambos tendrían que estar en la misma red.

Deja un comentario

Tu dirección de correo electrónico no será publicada.

Time limit is exhausted. Please reload the CAPTCHA.