notification - onmessagereceived firebase android
Firebase FCM notificaciones carga Ăștil click_action (9)
Ahora es posible configurar click_action en Firebase Console. Simplemente vaya a la opción de notificaciones-enviar mensaje-avanzado y allí tendrá dos campos para clave y valor. En el primer campo pones click_action y en el segundo pones un texto que representa el valor de esa acción. Y agrega filtro de intención en su Manifiesto y le da el mismo valor que escribió en la consola. Y esa es la simulación de una acción de clic real.
Estoy tratando de abrir una actividad particular cuando el usuario hace clic en la notificación cuando la aplicación está en segundo plano. De los documentos, tengo que click_action tiene que agregarse en la carga útil y un filtro de intención en la aplicación para manejarlo. Pero, ¿cómo agregar click_action en las notificaciones de Firebase a través de Firebase Console? Estoy abierto a cualquier otro Work Around también. Gracias por adelantado.
Bueno, esto está claro por los documentos de Firebase que su
onMessageReceived
no funcionará cuando la aplicación esté en segundo plano.
Cuando su aplicación esté en segundo plano y haga clic en su notificación, se iniciará su iniciador predeterminado.
Para iniciar la actividad deseada, debe especificar
click_action
en su carga de notificación.
$noti = array
(
''icon'' => ''new'',
''title'' => ''title'',
''body'' => ''new msg'',
''click_action'' => ''your activity name comes here''
);
Y en tu archivo
android.manifest
Agregue el siguiente código donde registró su actividad
<activity
android:name="your activity name">
<intent-filter>
<action android:name="your activity name" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
Esto cae en la categoría de solución alternativa, que también contiene información adicional:
Dado que las notificaciones se manejan de manera diferente según el estado de la aplicación (primer plano / fondo / no lanzado), he visto la mejor manera de implementar una clase auxiliar donde la actividad seleccionada se inicia en función de los datos personalizados enviados en el mensaje de notificación.
- cuando la aplicación esté en primer plano, use la clase auxiliar en onMessageReceived
- cuando la aplicación está en segundo plano, use la clase auxiliar para manejar la intención en onNewIntent de la actividad principal (verifique los datos personalizados específicos)
- cuando la aplicación no se esté ejecutando, use la clase auxiliar para manejar la intención en onCreate de la actividad principal (llame a getIntent para la intención).
De esta manera, no necesita el filtro click_action o intent específico para él. Además, escribe el código solo una vez y puede iniciar razonablemente cualquier actividad de manera razonable.
Entonces, los datos personalizados mínimos se verían así:
Key: run_activity
Value: com.mypackage.myactivity
Y el código para manejarlo:
if (intent.hasExtra("run_activity")) {
handleFirebaseNotificationIntent(intent);
}
private void handleFirebaseNotificationIntent(Intent intent){
String className = intent.getStringExtra("run_activity");
startSelectedActivity(className, intent.getExtras());
}
private void startSelectedActivity(String className, Bundle extras){
Class cls;
try {
cls = Class.forName(className);
}catch(ClassNotFoundException e){
...
}
Intent i = new Intent(context, cls);
if (i != null) {
i.putExtras(extras);
this.startActivity(i);
}
}
Ese es el código para los últimos dos casos, startSelectedActivity también se llamaría desde onMessageReceived (primer caso).
La limitación es que todos los datos en la intención adicional son cadenas, por lo que es posible que deba manejar eso de alguna manera en la actividad misma. Además, esto se simplifica, probablemente no se deba cambiar la Actividad / Vista en una aplicación que está en primer plano sin avisar a su usuario.
Estoy buscando que Firebase sea, el desarrollo de la notificación push de mensajería en la nube de Google es fundamental para que podamos usar el tutorial, la función y la implementación de gcm en firebase, estoy usando la función de la función de notificación push de gcm para resolver este problema de click_action, uso la función gcm **
''notificaciónclick''
** intente guardar url click_action en variable url esto está en server-worker.js
var url = "";
messaging.setBackgroundMessageHandler(function(payload) {
console.log(''[firebase-messaging-sw.js] Received background message '', payload);
// Customize notification here
url = payload.data.click_action;
const notificationTitle = payload.data.title;
const notificationOptions = {
body: payload.data.body ,
icon: ''firebase-logo.png''
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
//i got this in google cloud messaging push notification
self.addEventListener(''notificationclick'', function (event) {
event.notification.close();
var clickResponsePromise = Promise.resolve();
clickResponsePromise = clients.openWindow(url);
event.waitUntil(Promise.all([clickResponsePromise, self.analytics.trackEvent(''notification-click'')]));
});
Por lo que puedo decir, en este punto no es posible configurar click_action en la consola.
Si bien no es una respuesta estricta sobre cómo obtener el conjunto click_action en la consola, puede usar curl como alternativa:
curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send -d "{/"to/":/"/topics/news/",/"notification/": {/"title/": /"Click Action Message/",/"text/": /"Sample message/",/"click_action/":/"OPEN_ACTIVITY_1/"}}"
Esta es una manera fácil de probar la asignación de click_action. Requiere un filtro de intención como el especificado en los documentos de FCM:
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Esto también hace uso de temas para establecer la audiencia. Para que esto funcione, deberá suscribirse a un tema llamado "noticias".
FirebaseMessaging.getInstance().subscribeToTopic("news");
A pesar de que toma varias horas ver un tema recién creado en la consola, aún puede enviarle mensajes a través de la API FCM.
Además, tenga en cuenta que esto solo funcionará si la aplicación está en segundo plano. Si está en primer plano, deberá implementar una extensión de FirebaseMessagingService. En el método onMessageReceived, deberá navegar manualmente a su destino click_action:
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//This will give you the topic string from curl request (/topics/news)
Log.d(TAG, "From: " + remoteMessage.getFrom());
//This will give you the Text property in the curl request(Sample Message):
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//This is where you get your click_action
Log.d(TAG, "Notification Click Action: " + remoteMessage.getNotification().getClickAction());
//put code here to navigate based on click_action
}
Como dije, en este momento no puedo encontrar una manera de acceder a las propiedades de la carga útil de notificaciones a través de la consola, pero pensé que esta solución podría ser útil.
Puede manejar todas sus acciones en función de su mensaje en onMessageReceived () en su servicio que extiende FirebaseMessagingService. Para hacerlo, debe enviar un mensaje que contenga exclusivamente datos, utilizando, por ejemplo, el cliente REST avanzado en Chrome . Luego, envía una POST a https://fcm.googleapis.com/fcm/send usando en "Encabezados sin formato":
Tipo de contenido: aplicación / json Autorización: clave = YOUR_PERSONAL_FIREBASE_WEB_API_KEY
Y un mensaje json en el campo "Carga bruta".
Advertencia, si existe el campo "notificación" en su json, su mensaje nunca será recibido cuando la aplicación esté en segundo plano en onMessageReceived (), ¡incluso si hay un campo de datos! Por ejemplo, al hacer eso, el mensaje funciona solo si la aplicación está en primer plano:
{
"condition": " ''Symulti'' in topics || ''SymultiLite'' in topics",
"priority" : "normal",
"time_to_live" : 0,
"notification" : {
"body" : "new Symulti update !",
"title" : "new Symulti update !",
"icon" : "ic_notif_symulti"
},
"data" : {
"id" : 1,
"text" : "new Symulti update !"
}
}
¡Para recibir su mensaje en todos los casos en onMessageReceived (), simplemente elimine el campo "notificación" de su json!
Ejemplo:
{
"condition": " ''Symulti'' in topics || ''SymultiLite'' in topics",
"priority" : "normal",
"time_to_live" : 0,,
"data" : {
"id" : 1,
"text" : "new Symulti update !",
"link" : "href://www.symulti.com"
}
}
y en tu FirebaseMessagingService:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String message = "";
obj = remoteMessage.getData().get("text");
if (obj != null) {
try {
message = obj.toString();
} catch (Exception e) {
message = "";
e.printStackTrace();
}
}
String link = "";
obj = remoteMessage.getData().get("link");
if (obj != null) {
try {
link = (String) obj;
} catch (Exception e) {
link = "";
e.printStackTrace();
}
}
Intent intent;
PendingIntent pendingIntent;
if (link.equals("")) { // Simply run your activity
intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
} else { // open a link
String url = "";
if (!link.equals("")) {
intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(link));
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
}
pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = null;
try {
notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notif_symulti) // don''t need to pass icon with your message if it''s already in your app !
.setContentTitle(URLDecoder.decode(getString(R.string.app_name), "UTF-8"))
.setContentText(URLDecoder.decode(message, "UTF-8"))
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentIntent(pendingIntent);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (notificationBuilder != null) {
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(id, notificationBuilder.build());
} else {
Log.d(TAG, "error NotificationManager");
}
}
}
}
¡A disfrutar!
Si su aplicación está en segundo plano, Firebase no activará onMessageReceived (). Por qué.....? No tengo idea. En esta situación, no veo ningún punto en la implementación de FirebaseMessagingService.
Según los documentos, si desea procesar la llegada del mensaje de fondo, debe enviar ''click_action'' con su mensaje. Pero no es posible si envía un mensaje desde la consola de Firebase, solo a través de la API de Firebase. Significa que tendrá que construir su propia "consola" para que la gente de marketing pueda usarla. ¡Entonces, esto hace que la consola Firebase también sea bastante inútil!
Hay una idea realmente buena y prometedora detrás de esta nueva herramienta, pero se ejecuta mal.
¡Supongo que tendremos que esperar nuevas versiones y mejoras / arreglos!
Si su aplicación está en segundo plano, Firebase no activará onMessageReceived (). Se llama a onMessageReceived () cuando la aplicación está en primer plano. Cuando la aplicación está en segundo plano, se llamará al método onMessageReceived () solo si el cuerpo de https://fcm.googleapis.com/fcm/send contiene solo carga útil de datos. Aquí, acabo de crear un método para crear notificaciones personalizadas con la intención de tener es su actividad requerida y llamó a este método en onMessageRecevied ().
En PostMan:
uri: https://fcm.googleapis.com/fcm/send
encabezado: Autorización: clave = clave ur
cuerpo --- >>
{ "data" : {
"Nick" : "Mario",
"Room" : "PoSDenmark",
},
"to" : "xxxxxxxxx"
}
en su solicitud
class MyFirebaseMessagingService extends FirebaseMessagingService {
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getData().size() > 0) {
sendNotification("ur message body") ;
}
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, Main2Activity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
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)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle("FCM Message")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
cuando la carga útil de datos llega al móvil, se llamará al método onMessageReceived () ... dentro de ese método, acabo de hacer una notificación personalizada. Esto funcionará incluso si su aplicación es de fondo o de primer plano.
Actualizar:
Entonces, solo para verificar, actualmente no es posible establecer el parámetro
click_action
través de Firebase Console.
Así que he estado tratando de hacer esto en la consola de notificaciones de Firebase sin suerte.
Como parece que no puedo encontrar ningún lugar para colocar el valor de
click_action
en la consola, lo que hice principalmente para probar esto es agregar un par clave / valor personalizado en la Notificación (Opciones avanzadas> Datos personalizados):
Key: click_action
Value: <your_preferred_value>
luego intenté llamar a
RemoteMessage.getNotification().getClickAction()
en
onMessageReceived()
para ver si estaba recuperando el valor correcto, pero siempre devuelve
null
.
Entonces, intenté llamar a
RemoteMessage.getData (). Get (<especificada_clave>)
y pude recuperar el valor que agregué.
NOTA : No estoy completamente seguro de si está bien si se usa como solución alternativa o si está en contra de las mejores prácticas. Sugeriría usar su propio servidor de aplicaciones, pero su publicación es específica de Firebase Console.
La forma en que se comporta la aplicación cliente y la notificación aún depende de cómo la programe.
Dicho esto, creo que puede usar lo anterior como una solución alternativa, usando el valor recuperado de
getData()
, y luego haciendo que la Notificación llame a esto o aquello.
Espero que esto ayude de alguna manera.
¡Aclamaciones!
:RE