# MIMOGCM GOOGLE CLOUD MESSAGING 1
Jul 18, 2015
# MIMOGCM
GOOGLE CLOUD MESSAGING
1
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
INTRODUCCIÓN
• Servicio que permite enviar y recibir* datos entre nuestro servidor y dispositivos Android
• Gratuito y sin límite de uso
• El servicio se encarga de encolar y del envío de los datos a los usuarios
# MIMOGCM
INTRODUCCIÓN
• No tiene porqué desembocar siempre en una notificación visual:
• Pueden llevar carga útil (payload)
• Señal para sincronizar
• Posibilidad de enviar acuses de recibo
# MIMOGCM
INTRODUCCIÓN
• GCM es una evolución de un servicio llamado C2DM
• Tenía un límite de 1kb por notificación
• Cuota de 200k peticiones por servidor / día
http://developer.android.com/google/gcm/c2dm.html
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
CONCEPTOS• Actores
• Credenciales
• API Key
# MIMOGCM
CONCEPTOS - ACTORES
GCM • Comunica las partes • Registro, envío
y comunicación resultado
Servidor propio • Contiene lógica de
negocio del envío • HTTP • XMPP
Cliente Android • Aplicación que recibe
notificaciones y puede responder*
# MIMOGCM
CONCEPTOS - CREDENCIALES
• Hay varias credenciales que el conjunto del sistema maneja para establecer las conexiones • Sender ID: utilizado para permitir enviar mensajes a las apps
• Sender Auth Token: utilizado para ‘autenticarse’ con GCM
• Application ID: identificador de una aplicación cliente (Android)
• Registration ID: identificador de un dispositivo de una app
# MIMOGCM
CONCEPTOS - API KEY• Para poder utilizar GCM hay que crear un proyecto
en la consola de Google Developer • En esta ventana ya obtenemos el Sender ID, que debe ser
único
https://console.developers.google.com/project
# MIMOGCM
CONCEPTOS - API KEY• Posteriormente hay que activar el API de
Google Cloud Messaging • En APIs y autenticación > APIs : Google Cloud Messaging
# MIMOGCM
CONCEPTOS - API KEY
• Hay que solicitar el API Key para el servidor y la app Android
# MIMOGCM
CONCEPTOS - API KEY• Clave del servidor :
Sender Auth Token
# MIMOGCM
CONCEPTOS - API KEY• Clave de la app Android:
• Se extrae del keystore con el que se firman las apps y se combina con el paquete de la app
• keytool -list -v -keystore /Users/user/.android/debug.keystore
# MIMOGCM
CONCEPTOS - API KEY
Application ID
• Clave de la app Android: • Se extrae del keystore con el que se firman las apps y se
combina con el paquete de la app
# MIMOGCM
CONCEPTOS - API KEY• A veces al pedir el API para GCM tardan
en validarte para poder utilizar el servicio, aunque se supone que es automático
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
ARQUITECTURA• Esquema
• Mensajes
# MIMOGCM
ARQUITECTURA - ESQUEMA
La arquitectura corresponde a un cliente - servidor - cliente, ya que nuestro servidor actúa de servidor de la app Android y de cliente de GCM
# MIMOGCM
ARQUITECTURA - ESQUEMA
La arquitectura dependerá en parte del protocolo que decidamos implementar en nuestro servidor
HTTP XMPP
# MIMOGCM
ARQUITECTURA - MENSAJES
• Se comparten campos entre los dos protocolos pero algunos son específicos
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
FLUJOS DE INTERACCIÓN
• Servidor HTTP
• Servidor XMPP
• Pros / contras
# MIMOGCM
1. El dispositivo Android hace una petición a GCM para registrarse
2. GCM responde con el Registration ID al dispositivo
3. El dispositivo manda a nuestro servidor el RegID
FLUJOS INTERACCIÓN - HTTP
# MIMOGCM
4. Nuestro servidor responde con el resultado de la operación
5. Cuándo se quiere mandar una notificación, el servidor manda a GCM el regID del dispositivo
6. GCM envía la notificación al dispositivo
FLUJOS INTERACCIÓN - HTTP
# MIMOGCM
FLUJOS INTERACCIÓN - HTTP
• Puede recibir mensajes con carga útil de hasta 4kb
• El envío de notificaciones es síncrono en el servidor, tiene que llegar la respuesta para poder mandar otra
• El formato es JSON y se puede mandar texto plano
• Permite hacer multicast de una notificación con varios regID’s
# MIMOGCM
1. El dispositivo Android hace una petición a GCM para registrarse
2. GCM responde con el Registration ID al dispositivo
3. El dispositivo manda a GCM el RegID
FLUJOS INTERACCIÓN - XMPP
# MIMOGCM
4. GCM envía a nuestro servidor el nuevo RegID
5. Cuándo se quiere mandar una notificación, el servidor manda a GCM el RegID del dispositivo
6. GCM envía la notificación al dispositivo
FLUJOS INTERACCIÓN - XMPP
# MIMOGCM
FLUJOS INTERACCIÓN - XMPP
• Puede recibir y enviar mensajes con carga útil de hasta 4kb
• El envío de notificaciones es asíncrono en el servidor. GCM enviará el resultado (ACK o NACK) de cada petición de manera asíncrona
• Hay que usar el protocolo XMPP encapsulando JSON
• No se puede realizar multicast de mensajes
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
CLIENTE ANDROID
• Requisitos
• Permisos
• Registro / borrar
• Recibir notificaciones
• Enviar mensajes al servidor
# MIMOGCM
ANDROID - REQUISITOS• Como mínimo, el dispositivo con Android 2.2 con
la Google Play Store
• Si se quiere poder utilizar las características introducidas en las actualizaciones de Google Play Services, deberá ser Android 2.3
• Si es menor que 3.0, habrá de estar autenticado con una cuenta de Google; a partir de 4.0.4 no es necesario
# MIMOGCM
ANDROID - PLAY SERVICES
• Se debe agregar Google Play Services como dependencia del proyecto:
• Eclipse : proyecto librería descargado con SDK
• Gradle: dependencies { compile 'com.google.android.gms:play-services:6.5.87'}
# MIMOGCM
ANDROID - PLAY SERVICES• Se debe comprobar que el dispositivo tiene
instaladas las Google Play Services: private boolean checkPlayServices() { int resultCode = GooglePlayServicesUtil .isGooglePlayServicesAvailable(getActivity()); if (resultCode != ConnectionResult.SUCCESS) { if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) { GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), RC_RES_REQUEST).show(); } else { Log.i(LOG_TAG, "This device is not supported."); } return false; } return true; }
# MIMOGCM
ANDROID - PERMISOS
• Añadir al Manifest los siguientes permisos <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.GET_ACCOUNTS"/><uses-permission android:name="android.permission.WAKE_LOCK"/><uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/> <permission android:name="es.upsa.mimo.gcm.permission.C2D_MESSAGE" android:protectionLevel="signature"/><uses-permission android:name="es.upsa.mimo.gcm.permission.C2D_MESSAGE"/>
com.google.android.c2dm.permission.RECEIVE : necesario para registrar y recibir datos a GCM
es.upsa.mimo.gcm.permission.C2D_MESSAGE : necesario para registrar y recibir datos a GCM y que otras apps no puedan leer tus datos
# MIMOGCM
ANDROID - PERMISOS
• Añadir el BroadcastReceiver <application> <receiver android:name="GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE"/> <category android:name="es.upsa.mimo.gcm"/> </intent-filter> </receiver> </application>
• Debe extender WakefulBroadcastReceiver para que el sistema levante la app y no la mate mientras procesa la petición
# MIMOGCM
ANDROID - PERMISOS
• Añadir el Service <application> <service android:name=".GcmIntentService"/></application>
• Este servicio se encargará de procesar el Intent proveniente de GCM. No será eliminado por el sistema
# MIMOGCM
ANDROID - REGISTRAR GCM• Un lugar usual para hacerlo es el onCreate del objeto
Application, pero se puede hacer en cualquier momento
private void register() { try {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); String regid = gcm.register(mSenderId); sendRegistrationIdToBackend(gcm, regid); } catch (IOException e) { // If there is an error, don't just keep trying to register. // Require the user to click a button again, or perform // exponential back-off. }}
# MIMOGCM
ANDROID - REGISTRAR GCM• En la implementación con XMPP, mandamos el
regID a GCM private void sendRegistrationIdToBackend(GoogleCloudMessaging gcm, String regId) { try { String msgId = Integer.toString(getNextMsgId()); gcm.send(mSenderId + "@gcm.googleapis.com", msgId, Constants.GCM_DEFAULT_TTL, data); } catch (IOException e) { Log.e(LOG_TAG, "IOException while sending registration to backend...", e); }}
• Con HTTP, a nuestro backend
# MIMOGCM
ANDROID - REGISTRAR GCM• Borrar el regID no es común, la propagación
es lenta y puede llevar a errores
private void register() { try {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); String regid = gcm.unregister(); } catch (IOException e) { // If there is an error, don't just keep trying to register. // Require the user to click a button again, or perform // exponential back-off. }}
http://developer.android.com/google/gcm/gcm.html#unreg
# MIMOGCM
ANDROID - RECIBIR NOTIF• En el GcmIntentService se recibirá el mensaje
y se procesará para comprobar lo recibido if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) { sendNotification("Send error: " + extras.toString(), false);} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) { sendNotification("Deleted messages on server: " + extras.toString(), false); // If it's a regular GCM message, do some work.} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { // Post notification of received message. String msg = extras.getString(Constants.GCM_FIELD_MESSAGE); sendNotification(msg, hasPayload); Log.i(LOG_TAG, "Received: " + extras.toString() + ", sent: " + msg);}
# MIMOGCM
ANDROID - ENVIAR MENSAJES• Se denomina Upstream Messaging
• Permite generar nuestro propio protocolo de mensajes, p.ejemplo mensajes de ‘echo’
private void sendMessage(GoogleCloudMessaging gcm, Intent intent) { try { String msg = intent.getStringExtra(Constants.KEY_MESSAGE_TXT); Bundle data = new Bundle(); data.putString(Constants.ACTION, Constants.ACTION_ECHO); data.putString("message", msg); String id = Integer.toString(getNextMsgId()); gcm.send(mSenderId + "@gcm.googleapis.com", id, data); Log.v(LOG_TAG, "sent message: " + msg); } catch (IOException e) { Log.e(LOG_TAG, "Error while sending a message", e); }}
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
SERVIDOR HTTP
• Características
• Autenticar
• Formato peticiones
• Envío mensajes
• Respuesta GCM
• Multicast
# MIMOGCM
HTTP - CARACTERÍSTICAS
• Primer método de interacción con GCM
• Las peticiones pueden ser en JSON o texto plano
• Más sencillo de implementar
# MIMOGCM
HTTP - AUTENTICACIÓN
• Las peticiones se realizan contra esta URL : https://android.googleapis.com/gcm/send
• En el header de la petición hay que enviar:
• Authorization: API Key para realizar la autenticación
• Content-Type : application/json o application/x-www-form-urlencoded;charset=UTF-8
# MIMOGCM
HTTP - FORMATO PETICIONES
• Se pueden construir en formato JSON o texto plano{ "registration_ids": [ "42" ] } registration_id=42
http://developer.android.com/google/gcm/http.html#request
# MIMOGCM
HTTP - ENVÍO MENSAJES• Hay que configurar el mensaje a enviar, al menos con un regID
• Atributos de los mensajes: • registrations_id : regID del dispositivo registrado • collapse_key : indicador de agrupador de notificaciones • restricted_package_id : package de la app de envío • delay_while_idle : indica si GCM ha de guardar el mensaje si el dispositivo
está offline • timeToLive : tiempo máximo(s) que guarda GCM la notificación si el dispositivo
está offline • data : carga útil del mensaje
# MIMOGCM
HTTP - RESPUESTA• Al enviar un mensaje, GCM nos puede contestar dos
cosas:
• HTTP 200 : el body de la respuesta tiene el body que enviamos con info adicional, incluidos posibles errores
• HTTP 4XX-5XX : GCM ha rechazado el envío
• Los errores más comunes son Unavailable y NotRegistered
http://developer.android.com/google/gcm/server-ref.html#error-codes
# MIMOGCM
HTTP - MULTICAST
• Esta implementación nos permite enviar la misma notificación a varios regID’s (array)
• Petición síncrona
• Respuesta es un resumen de la operación total
• Como máximo 1000 receptores
# MIMOGCM
HTTP - MULTICAST
{ "multicast_id": 216, "success": 3, "failure": 3, "canonical_ids": 1, "results": [ { "message_id": "1:0408" }, { "error": "Unavailable" }, { "error": "InvalidRegistration" }, { "message_id": "1:1516" }, { "message_id": "1:2342", "registration_id": "32" }, { "error": "NotRegistered"} ]}
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
SERVIDOR XMPP
• Características
• ¿Qué es XMPP?
• Explicación ejemplo
• Conectar
• Autenticar
• Recepción mensajes
• Envío mensajes
• ACK y NACK
• Errores posibles
# MIMOGCM
XMPP - CARACTERÍSTICAS
• Google llama a su implementación Cloud Connection Server
• Servidor de conexión asíncrona
• Permite recibir mensajes de los dispositivos
• Se optimiza la batería, ya que se utilizan conexiones existentes con Play Services
# MIMOGCM
XMPP - ¿QUÉ ES?
• Protocolo utilizado en aplicaciones con conexiones en tiempo real (chat)
• Está basado en mensajes XML, pero CCS encapsula carga útil JSON
• Usado en Google Talk hasta 2013
# MIMOGCM
XMPP - EJEMPLO
• Realizado en Play Java 2.4
• Usa una librería XMPP muy extendida, Smack
• Para el procesamiento de JSON, json-simple
• Persiste usuarios (mails) y regIDs en memoria
• Recibe mensajes echo y devuelve notificaciones
• Implementa UserNotifications
# MIMOGCM
XMPP - EJEMPLO
• Arrancar sin IDE -> activator compile / run
• Arrancar con IDE -> Intellij Ultimate con plugin Scala (incluye Play!)
• Por defecto se muestra consola de debug de peticiones XMPP
# MIMOGCM
XMPP - CONECTAR• Primer paso en la interacción
• Google ofrece un entorno de producción y uno de preproducción:
• gcm.googleapis.com:5235
• gcm-preprod.googleapis.com:5236
• La conexión debe estar establecida en todo momento
• Se debe realizar con el TLS (https)
# MIMOGCM
XMPP - CONECTARpublic void connect() throws XMPPConnectionError { config = new ConnectionConfiguration(Constants.GCM_SERVER, Constants.GCM_PORT); config.setSecurityMode(SecurityMode.enabled); config.setReconnectionAllowed(true); config.setRosterLoadedAtLogin(false); config.setSendPresence(false); config.setSocketFactory(SSLSocketFactory.getDefault()); connection = new XMPPTCPConnection(config); connection.addConnectionListener(new GCMConnectionListener(logger)); // Handle incoming packets connection.addPacketListener(this, new PacketTypeFilter(Message.class)); // Log all outgoing packets connection.addPacketInterceptor(new PacketInterceptor() { @Override public void interceptPacket(Packet packet) { logger.log(Level.INFO, "Sent: {0}", packet.toXML()); } }, new PacketTypeFilter(Message.class)); try { connection.connect(); } catch (SmackException e) { throw new XMPPConnectionError("Smack Exception found", e); } catch (IOException e) { throw new XMPPConnectionError("IOException Exception found", e); } catch (XMPPException e) { throw new XMPPConnectionError("XMPP Exception found", e); } }
# MIMOGCM
XMPP - AUTENTICAR• Utilizamos el Sender ID y el API Key que se
envia en la trama tipo
<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">APIKEY</auth>
<stream:stream from="gcm.googleapis.com" id="37B21BC7F54D2600" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"> <iq id="d4eS3-0" type="result"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>[email protected]/Smack64F9FF78</jid></bind></iq>
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
# MIMOGCM
XMPP - AUTENTICAR• Utilizamos el Sender ID que se envia en la
trama tipopublic void authenticate() throws XMPPAuthenticationError { try { connection.login(mProjectId + "@gcm.googleapis.com", mApiKey); } catch (XMPPException e) { throw new XMPPAuthenticationError("XMPP Exception found", e); } catch (SmackException e) { throw new XMPPAuthenticationError("Smack Exception found", e); } catch (SaslException e) { throw new XMPPAuthenticationError("Sasl Exception found", e); } catch (IOException e) { throw new XMPPAuthenticationError("IOException found", e); } }
# MIMOGCM
XMPP - RECIBIR• Una vez conectados y autenticados, ya se pueden
comenzar a recibir mensajes
• Atributos de los mensajes: • category : package de la app de envío • message_id : id del mensaje (único) • from : regID del dispositivo registrado • timeToLive : tiempo máximo(s) que guarda GCM la notificación
si el dispositivo está offline • data : carga útil del mensaje
# MIMOGCM
XMPP - RECIBIR
<message to="[email protected]" from="[email protected]" type="normal"> <gcm xmlns="google:mobile:data"> { "category": "es.upsa.mimo.gcm", "data": { "action": "es.upsa.mimo.gcm.REGISTER", "account": "[email protected]" }, "time_to_live": 86400, "message_id": "4", "from": "regId asignado" } </gcm> </message>
http://developer.android.com/google/gcm/server-ref.html#interpret-upstream
# MIMOGCM
XMPP - ENVIAR• El servidor puede iniciar el proceso de enviar una
notificación
• Atributos de los mensajes: • collapse_key : indicador de agrupador de notificaciones • delay_while_idle : indica si GCM ha de guardar el mensaje si el dispositivo
está offline • message_id : id del mensaje (único) • to : regID del dispositivo destino • timeToLive : tiempo máximo(s) que guarda GCM la notificación si el
dispositivo está offline • data : carga útil del mensaje
# MIMOGCM
XMPP - ENVIAR
<message id="d4eS3-8"> <gcm xmlns="google:mobile:data"> { "collapse_key": "sample_collapse", "delay_while_idle": true, "data": { "message": "Hi MIMO" }, "time_to_live": 10000, "message_id": "m--9206142069423346343", "to": "regID Destino" } </gcm> </message>
http://developer.android.com/google/gcm/server-ref.html#upstream-response
# MIMOGCM
XMPP - ACK Y NACK• XMPP es un protocolo con confirmación, tenemos que
notificar el éxito o fracaso a la hora de realizar alguna operación, así como nosotros lo seremos
• Los ACK (acknowledge) indican que la operación ha ido bien y el extremo lo notifica
• Atributos de los mensajes ACK: • from : regID desde el que se originó el mensaje • message_id : id del mensaje (único) • message_type : en este caso ACK
<message> <data:gcm xmlns:data="google:mobile:data"> { "message_id": "m--9206142069423346343", "from": "regID" "message_type": "ack" } </data:gcm> </message>
# MIMOGCM
XMPP - ACK Y NACK
• En CCS hay dos tipos de NACK:
• NACK de protocolo : las ‘stanzas’ XML de XMPP recogerán la definición del error
• NACK de GCM : error relacionado con la comunicación
# MIMOGCM
XMPP - ACK Y NACK<message id="iUB3B-2" to="[email protected]" type="error"> <error code="400" type="MODIFY"> <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> <text xml:lang="en" xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"> InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id </text> </error> <gcm xmlns="google:mobile:data"> { "to":"someRegId", "delay_while_idle":true, "data": { "message": "Simple sample sessage" }, "time_to_live":120000 } </gcm> </message>
<message> <data:gcm xmlns:data="google:mobile:data"> { "message_id": "m-1815828951840878009", "from": "regID", "error_description": "", "error": "DEVICE_UNREGISTERED", "message_type": "nack" } </data:gcm> </message>
http://developer.android.com/google/gcm/server-ref.html#error-codes
# MIMOGCM
XMPP - ACK Y NACK• El manejo de las confirmaciones es delicado
• Si el servidor XMPP llega a una cuenta de 100 mensajes sin recibir ACK o NACK debería dejar de mandar mensajes
• Si XMPP manda muchos NACK, CCS deja de mandarnos mensajes, debemos confirmar todos los posibles
• Si se cierra o pierde la conexión, al reiniciar no se debe mandar ACK O NACK pendientes; hay que esperar al reenvío.
http://developer.android.com/google/gcm/ccs.html#flow
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
USER NOTIFICATIONS
• Concepto
• Operaciones
• Envío mensajes
• Limitaciones
# MIMOGCM
USER NOTIFICATIONS- CONCEPTO
• Mecanismo ideado para enlazar varios registration ID de un único usuario
• El objetivo es enlazar todas las notificaciones enviadas a un mismo usuario a varios dispositivos
• El ejemplo más extendido es el de un cliente de correo, al consumir la notificación en un dispositivo se borra de los demás
# MIMOGCM
USER NOTIFICATIONS- CONCEPTO
• Se puede utilizar en servidores HTTP o XMPP
• Los registration ID se agrupan en notification_key de tal manera que al enviar una notificación a esta key, se envía a todas sus asociadas
• Los notification_key se pueden generar tanto en el servidor como en el cliente
# MIMOGCM
USER NOTIFICATIONS - OPERACIONES
• Las operaciones se realizan en con peticiones POST a esta URL :
• https://android.googleapis.com/gcm/notification • Se han de configurar los headers de las peticiones con
estos parámetros:
• content-type: "application/json"
• Header : "project_id": <projectID>
• Header: "Authorization", "key=API_KEY"
# MIMOGCM
USER NOTIFICATIONS - OPERACIONES
• Crear (servidor)
• Para crear un notification_key se aporta un notification_key_name . Así se identifica un usuario para una app.
• request: { "notification_key_name": "[email protected]", "registration_ids": [ "regID1", "regID2" ], "operation": "create"}
• En el cliente : http://developer.android.com/google/gcm/notifications.html#gen-client
# MIMOGCM
USER NOTIFICATIONS - OPERACIONES
• Añadir regID
• Se pueden asociar como máximo 20 dispositivos a un notification_key
• request: { "operation": "add", "notification_key_name": "[email protected]", "notification_key": "#generatedNotifKey", "registration_ids": ["regID4", "regID5", "regID6"] }
# MIMOGCM
USER NOTIFICATIONS - OPERACIONES
• Eliminar regID
• request:{ "operation": "remove", "notification_key_name": "[email protected]", "notification_key": "#generatedNotifKey", "registration_ids": ["regID4", "regID5", "regID6"] }
# MIMOGCM
USER NOTIFICATIONS - ENVÍO MENSAJES
• Se envía como un mensaje estándar de formato HTTP pero con el campo notification_key en vez de registration_ids
# MIMOGCM
USER NOTIFICATIONS - ENVÍO MENSAJES
• Desde el cliente Android se envía un mensaje al notification_key deseado, utilizando la librería Google Cloud Messaging.
• Internamente es un mensaje XMPPGoogleCloudMessaging gcm = GoogleCloudMessaging.get(context); String to = NOTIFICATION_KEY; AtomicInteger msgId = new AtomicInteger(); String id = Integer.toString(msgId.incrementAndGet()); Bundle data = new Bundle(); data.putString("hello", "world"); gcm.send(to, id, data);
# MIMOGCM
USER NOTIFICATIONS - LIMITACIONES
• Existe un límite de dispositivos
• Los errores en los envíos han de ser gestionados por nuestro servidor
• Un error en todos es un HTTP 503
{ "success": 2, "failure": 0 }
{ "success":1, "failure":2, "failed_registration_ids":[ "regId1", "regId2" ] }
# MIMOGCM
USER NOTIFICATIONS - LIMITACIONES
• No se pueden probar las User Notifications sin desplegar el servidor en Internet
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
WTF’S PUSHBULLET
https://blog.pushbullet.com/2014/02/12/keeping-google-cloud-messaging-for-android-working-reliably-techincal-post/
# MIMOGCM
WTF’S PUSHBULLET• Lección 1ª: GCM va a responder
frecuentemente SERVICE_NOT_AVAILABLE • Se obtiene una IOException al registrarse. • Solución : política reintento exponencial
• Lección 2ª : El registro puede haber fallado aunque tengas un regID • Se hace el registro, pero no devuelve el regID • Solución: leer Intent en BroadcastReceiver • com.google.android.c2dm.intent.REGISTRATION
# MIMOGCM
WTF’S PUSHBULLET
• Lección 3ª: Recuerda actualizar tu regID cada vez que actualizas la app
• Lección 4ª: Recuerda actualizar tu regID cuando se actualiza la versión de Android
# MIMOGCM
ÍNDICE
• Introducción
• Conceptos
• Arquitectura
• Flujos de interacción
• Cliente Android
• Servidor HTTP
• Servidor XMPP
• User notifications
• WTF’s
• Otras plataformas
# MIMOGCM
OTRAS PLATAFORMAS
• Introducción
• MBaaS
• Parse
# MIMOGCM
OTRAS PLATAFORMAS - INTRO
• El envío de notificaciones se ha convertido en un estándar de casi todas las plataformas móviles y la mayoría de las apps las utilizan
• Cada plataforma móvil implementa la comunicación de una manera distinta
• Como hemos visto, tener un servidor listo para producción y un gran número de usuarios puede ser complicado
# MIMOGCM
OTRAS PLATAFORMAS
• En este contexto han surgido varias plataformas para implementar servicios de notificaciones multiplataforma:
• Parse
• Urban Airship
• Amazon SNS
• Appcelerator
# MIMOGCM
OTRAS PLATAFORMAS - MBAAS
• Con el tiempo han ido surgiendo otro tipo de plataformas que agregan otro tipo de funcionalidad, se denominan Mobile Backend as a Service (MBaaS):
• Capacidades de persistencia
• Analíticas
• Conexión entre usuarios
• Proveedores de coordenadas
• …
# MIMOGCM
OTRAS PLATAFORMAS - PARSE
# MIMOGCM
OTRAS PLATAFORMAS - PARSE
• Las notificaciones de Parse están disponibles para Android, iOS, Windows Phone y Windows 8
• El servicio gratuito hasta un millón de envíos al mes, aunque es una parte
• El servicio ofrece una consola para el envío de las notificaciones, aunque podemos utilizar API’s para hacerlo desde nuestro backend
# MIMOGCM
OTRAS PLATAFORMAS - PARSE
• Las notificaciones están soportadas a partir de Android 2.3, aunque tienen una vertiente sin GCM (Amazon)
• Parse puede gestionar registros concurrentes en su servicio y en GCM
• El servicio ofrece una consola para el envío de las notificaciones, aunque podemos utilizar API’s para hacerlo desde nuestro backend
# MIMOGCM
OTRAS PLATAFORMAS - PARSE
https://parse.com/apps/quickstart#parse_push/android/existing
https://parse.com/tutorials/android-push-notifications
# MIMOGCM
OTRAS PLATAFORMAS - PARSE• Automáticamente se hará tracking del estado del
envío y apertura
• Podemos mandar una URI para abrir otra actividad o fragment
• Podemos crear nuestro propio protocolo, al poder enviar carga útil en formato JSON
• A/B testing del texto de notificacioneshttps://parse.com/docs/push_guide#top/Android
# MIMOGCM
ENLACES
http://bit.ly/1Bt1Ngp
http://bit.ly/1D3oZc6
# MIMOGCM
¡GRACIAS!