[mensaje-curso]
En el artículo anterior de la serie resolvimos el problema de la identificación de usuarios/dispositivos individuales a la hora de enviar mensajes a través de Firebase Cloud Messaging. En este nuevo artículo nos centraremos en explicar por qué las notificaciones que hemos enviado hasta ahora tan sólo aparecen en el dispositivo cuando nuestra aplicación se encuentra en segundo plano, y veremos lo sencillo que es resolverlo.
En el primer artículo de la serie vimos que cuando se recibía un mensaje sobre una aplicación que se encontraba en segundo plano el sistema generaba y mostraba automáticamente la notificación en el dispositivo sin necesidad de hacer nada por nuestra parte, incluso asignaba una acción por defecto a la notificación de forma que al pulsarla se iniciaba nuestra actividad principal.
Sin embargo, cuando el mensaje va dirigido a la aplicación que está en primer plano deberá ser la propia aplicación la que se encargue de realizar la gestión completa de dicho mensaje, es decir, el sistema no hará nada por nosotros, ni siquiera mostrar la notificación en la barra de estado o en la bandeja del sistema.
Solucionar esto es bastante sencillo, aunque requiere añadir un nuevo componente a la aplicación. Concretamente tendremos que añadir un nuevo servicio, esta vez extendiendo a FirebaseMessagingService. En esta clase tan sólo tendremos que sobrescribir un método llamado onMessageReceived(), que se llamará automáticamente cada vez que la aplicación reciba un mensaje de Firebase Cloud Messaging.
El método onMessageReceived() recibe como parámetro un objeto RemoteMessage que encapsula la información del mensaje recibido. Así, para acceder por ejemplo al título o al texto de la notificación podremos llamar a los métodos correspondientes, getTitle() y getBody() en este caso, sobre dicho objeto. Adicionalmente, si quisiéramos mostrar la notificación recibida en la barra de estado y la bandeja del sistema tendríamos que hacerlo por nosotros mismos, haciendo uso de NotificationCompat. Si necesitas más información sobre la generación de notificaciones en la barra de estado de Android puedes consultar el capítulo del curso dedicado a este tema.
Se muestra a continuación el código completo del servicio de recepción de mensajes. En mi caso de ejemplo me limito a mostrar los datos recibidos en el log del sistema y a generar una notificación en la barra de estado con dichos datos:
public class MyFirebaseMessagingService extends FirebaseMessagingService { private static final String LOGTAG = "android-fcm"; @Override public void onMessageReceived(RemoteMessage remoteMessage) { if (remoteMessage.getNotification() != null) { String titulo = remoteMessage.getNotification().getTitle(); String texto = remoteMessage.getNotification().getBody(); Log.d(LOGTAG, "NOTIFICACION RECIBIDA"); Log.d(LOGTAG, "Título: " + titulo); Log.d(LOGTAG, "Texto: " + texto); //Opcional: mostramos la notificación en la barra de estado showNotification(titulo, texto); } } private void showNotification(String title, String text) { NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(android.R.drawable.stat_sys_warning) .setContentTitle(title) .setContentText(text); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0, notificationBuilder.build()); } }
No hay que olvidar nunca incluir también la referencia al nuevo servicio en el fichero AndroidManifest.xml de nuestro proyecto de Android Studio:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.sgoliver.android.fcm"> <application ...> ... <service android:name=".MyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service> </application> </manifest>
Hecho esto, ya podríamos ejecutar de nuevo la aplicación y enviar un mensaje desde la consola de Firebase, esta vez sin necesidad de mandar la aplicación a segundo plano antes del envío. Tras enviar el mensaje podremos revisar el log de Android para ver los datos recibidos:
Adicionalmente, también debería haber aparecido la notificación en la barra de estado del dispositivo:
Con esto, acabamos de solucionar el segundo de los problemas que encontramos en nuestro capítulo inicial. Seguiremos mejorando la aplicación en próximos capítulos.
Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la página del curso en GitHub.
[mensaje-curso]
11 comentarios
Hola, quisiera poder reproducir sonido cuando llega la notificación con la app cerrada, como podría lograrlo? Siguiendo los 3 posts aún no pude. Muchas gracias.
Hola,
En el metodo showNotification del servicio puedes añadir Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
y a la hora de empaquetar en el Builder la notificación le añades .setSound(alarmSound)
Pero este caso sólo sirve cuando la Activity esta activa en pantalla. Cuando la app esta en segundo plano no he conseguido que realice el sonido.
Saludos
Hola de nuevo,
Para cuando la app esta en segundo plano es aún mas sencillo. A la hora de crear en mensaje mediante Firebase, en opciones avanzadas tienes la posibilidad de habilitar el sonido
Hola, gracias un excelente tutorial, la función remoteMessage.getNotification().getTitle() retorna nulo, y se que el dato está porque lo veo en el Map de remoteMessage y lo envío desde Firebase, alguna sugerencia? Gracias desde ya
hola, quiciera saber como hacer para al enviar un mensaje por medio de la base de datos Firebase en un celular me haga una notificación en otro, o sea sin necesidad de la consola de firebase. Si es posible. Gracias!
Hola, al momento de seleccionar mi icono para la notificación pongo:
.setSmallIcon(R.drawable.ic_stat_name)
Pero sólo muestra este icono cuando la notificación se recibe con la app abierta, en segundo plano sólo muestra un cuadro gris como icono.
Hay manera de mostrar mi icono cuando la notificación llega con la app en segundo plano?
Hola, me sumo a los comentarios y espero nos puedas brindar tu ayuda. Cuando el teléfono esta bloqueado y llega la notificación no emite un sonido personalizado(solo el default de notificaciones), tampoco enciende la pantalla automáticamente, cual sería una posible solución. Gracias de antemano.
sale valor nulo porque no estas colocando el valor en titulo, tienes que colocar el titulo en opciones avanzadas de firebase, en el texto de mensaje viaja el cuerpo.
muy buen post
hola estimado, le escribo para ver si puede ayudarme, tengo una aplicación que hicieron las notificaciones push con NotificationManager el problema que tengo y no tengo idea como solucionarlo es que las notificaciones no me aparecen cuando tengo la app cerrada, me da la impresión que salen solo cuando están en segundo plano. En xamarin en Vs 2017 Muchas Gracias
Buenas tardes! Muchísimas gracias por tu tiempo y por tu información.
Soy un alumno de ingeniería informática ya casi finalizando y estoy creando una aplicación Android que usa Firebase.
La cosa es que me gustaría que me llegase una notificación automática cuando la base de datos tenga alguna alteración, sobre todo cuando se añada algo a esta. Estoy loco buscando pero no me entero. Sería de gran ayuda cualquier pequeño detalle.
Gracias de nuevo.
Buenas tarde :)
A pesar de que he hecho todos los pasos, la notificación solo llega cuando la app está en segundo plano. Estando en primer plano no.
No sé cual sea el problema, a menos que sea el NotificationCompat que al parecer ya no tiene soporte, entonces ¿cual sería el método que lo reemplazó?
Muchas gracias por su tiempo!