studio - notificaciones push android firebase
Notificación expansible de Firebase Muestra la imagen cuando la aplicación está en segundo plano (6)
Los notification messages
FCM no son compatibles con largeIcon o bigPicture.
si los necesita en segundo plano, puede usar un data message
FCM.
Para los mensajes de datos, siempre se llama al método onMessageReceived(message)
, por lo que puede usar el método message.getData()
y crear su notificación personalizada.
Obtenga más información sobre los mensajes de notificación y los mensajes de datos aquí: https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages
Estoy implementando notificaciones de FCM en Android, pero ¿cómo difieren las notificaciones según el estado de la aplicación (de fondo frente a primer plano)?
Estoy enviando la notificación usando la API de FCM con Postman y esta es la estructura de notificación:
{ "notification": {
"title": "Notification title",
"body": "Notification message",
"sound": "default",
"color": "#53c4bc",
"click_action": "MY_BOOK",
"icon": "ic_launcher"
},
"data": {
"main_picture": "URL_OF_THE_IMAGE"
},
"to" : "USER_FCM_TOKEN"
}
La imagen a renderizar se toma de data.main_picture
.
Implementé mi propio FirebaseMessagingService
que hace que las notificaciones se muestren perfectamente en primer plano. El código de notificación es el siguiente:
NotificationCompat.BigPictureStyle notiStyle = new NotificationCompat.BigPictureStyle();
notiStyle.setSummaryText(messageBody);
notiStyle.bigPicture(picture);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(bigIcon)
.setContentTitle(title)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
.setStyle(notiStyle); code here
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
Sin embargo, en segundo plano, el servicio ni siquiera se ejecuta. En AndroidManifest.xml
, los servicios de Firebase se declaran de la siguiente manera:
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
Mi problema no es LargeIcon
o SmallIcon
sino que muestra la imagen completa.
Gracias por su apoyo.
Si esperas solo una notificación en una bandeja del sistema para tu aplicación, la siguiente solución puede resolver el problema, hasta que FCM presente la solución adecuada.
eliminar MyFirebaseMessagingService del manifiesto.
<service android:name=".MyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service>
- MyGcmReceiver Extiende la clase GcmReceiver y dirige la lógica de notificación.
Agregar MyGcmReceiver en manifiesto
<receiver android:name=".MyGcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <category android:name="package_name" /> </intent-filter> </receiver>
cancelar todas las notificaciones antes de notificar la notificación. (De lo contrario, firebase también muestra una notificación cuando la aplicación está en segundo plano)
Ver mi FirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FirebaseMessageService";
Bitmap bitmap;
/**
* Called when message is received.
*
* @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
//
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
//The message which i send will have keys named [message, image, AnotherActivity] and corresponding values.
//You can change as per the requirement.
//message will contain the Push Message
String message = remoteMessage.getData().get("message");
//imageUri will contain URL of the image to be displayed with Notification
String imageUri = remoteMessage.getData().get("image");
//If the key AnotherActivity has value as True then when the user taps on notification, in the app AnotherActivity will be opened.
//If the key AnotherActivity has value as False then when the user taps on notification, in the app MainActivity will be opened.
String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");
//To get a Bitmap image from the URL received
bitmap = getBitmapfromUrl(imageUri);
sendNotification(message, bitmap, TrueOrFlase);
}
/**
* Create and show a simple notification containing the received FCM message.
*/
private void sendNotification(String messageBody, Bitmap image, String TrueOrFalse) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("AnotherActivity", TrueOrFalse);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setLargeIcon(image)/*Notification icon image*/
.setSmallIcon(R.drawable.firebase_icon)
.setContentTitle(messageBody)
.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(image))/*Notification with Image*/
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
/*
*To get a Bitmap image from the URL received
* */
public Bitmap getBitmapfromUrl(String imageUrl) {
try {
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
return bitmap;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
Puede enviar mensajes utilizando esta herramienta de cliente de descanso. Al usar esta herramienta, también puede enviar mensajes a la aplicación del cliente en segundo plano y en primer plano. Para enviar un mensaje usando API, puede usar una herramienta llamada AdvancedREST Client, es una extensión de Chrome y enviar un mensaje con los siguientes parámetros.
Enlace de herramienta de cliente de reposo: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo
use esta url: - https://fcm.googleapis.com/fcm/send Tipo de contenido: application / json Authorization: key = Su clave de servidor Desde o la clave de Autorización (ver abajo ref)
{"data": {"image": " https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg ", "message": "Mensaje de Firebase Push usando la API" "AnotherActivity" : "Verdadero"}, "a": "identificador del dispositivo o token del dispositivo"}
La clave de autorización se puede obtener visitando la consola de desarrolladores de Google y haciendo clic en el botón Credenciales en el menú de la izquierda para su proyecto. Entre las claves API enumeradas, la clave del servidor será su clave de autorización.
Y necesita poner tokenID del receptor en la sección "a" de su solicitud POST enviada mediante API.
Y esta pieza del código de Android // mensaje contendrá el mensaje de inserción
String message = remoteMessage.getData().get("message1");
//imageUri will contain URL of the image to be displayed with Notification
String imageUri = remoteMessage.getData().get("image");
//If the key AnotherActivity has value as True then when the user taps on notification, in the app AnotherActivity will be opened.
//If the key AnotherActivity has value as False then when the user taps on notification, in the app MainActivity2 will be opened.
String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");
//To get a Bitmap image from the URL received
bitmap = getBitmapfromUrl(imageUri);
sendNotification(message, bitmap, TrueOrFlase);
Si su problema está relacionado con la visualización de una imagen grande, es decir, si está enviando notificaciones automáticas con una imagen de la consola de Firebase y muestra la imagen solo si la aplicación está en primer plano. La solución para este problema es enviar un mensaje de inserción solo con el campo de datos.
{ "data": { "image": "https://static.pexels.com/photos/4825/red-love-romantic-flowers.jpg", "message": "Firebase Push Message Using API" "AnotherActivity": "True" }, "to" : "device id Or Device token" }
Esto definitivamente resuelve el problema.
Enviar notificación de imagen grande desde la consola de Firebase: funciona tanto para la aplicación de fondo como para la de primer plano
En lugar de onMessageReceived, anule zzm () de FirebaseMessagingService y cree su notificación personalizada desde aquí
@Override
public void zzm(Intent intent) {
Log.e(TAG, "zzm : " + intent);
createBigPictureNotification();
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
}