Cordova-plugin-firebase: Cambio del icono de notificación push: problema del icono de Android en blanco en 2018

Creado en 6 jul. 2018  ·  22Comentarios  ·  Fuente: arnesson/cordova-plugin-firebase

Hola a todos,

Para las personas que usan este complemento con cordova 8+, es posible que el cambio de su ícono de notificación no funcione y presione el antiguo problema de 'el ícono de notificación es un cuadrado en blanco' en Android. Esto sucede porque los íconos de notificación de Android deben tener una forma simple de 1 color sobre un fondo transparente y si no ha proporcionado dicho ícono, Android usará el ícono de la aplicación en su lugar. Lo más probable es que sean cuadrados llenos y coloridos sin ningún fondo transparente.

Esto es muy molesto cuando se configura un nuevo proyecto de Ionic 3 y se intenta usar este complemento.

El archivo Léame aquí atm no describe el proceso de cambio de icono correctamente. Estos son los pasos que debe seguir para cambiar el icono:

0) Deja de buscar en Google y tirarte del pelo. Siga estas instrucciones paso a paso y lo hará funcionar, créame.
1) Prepare la versión del icono de su aplicación que tenga solo una forma de 1 color sobre fondo transparente
2) Vaya aquí: http://romannurik.github.io/AndroidAssetStudio/icons-notification.html#source.type=clipart&source.clipart=ac_unit&source.space.trim=1&source.space.pad=0&name=notification_icon presione "imagen" en la parte superior izquierda, cargue su icono, recórtelo / agregue relleno si es necesario
3) Si se ve bien, presione la flecha en la parte superior derecha para descargar las carpetas "dibujables". Le dará un zip con la carpeta res dentro y 5 carpetas drawable-xxx cada una con un tamaño diferente de su icono
4) Copie esas carpetas dibujables en algún lugar de su proyecto. Para mí, los copié junto al ícono y los recursos de la pantalla de presentación: project-root/resources/android/notification_icon
5) Configure su archivo config.xml para copiar esos archivos dentro de su aplicación de Android usando la directiva <resource-file /> . Tenga en cuenta que desde crodova 8.x, la ruta de destino correcta es app/src/main/res . En cordova <8 era solo res (ya que anteriormente los archivos de recursos se guardaban en el directorio platforms/android/res y ahora están en platforms/android/app/main/res ). La mayoría de los problemas 'resueltos' en línea en el icono de notificación de Android en blanco no lo mencionan.

<platform name="android">
(...) 
  <resource-file src="resources/android/notification_icon/drawable-mdpi/notification_icon.png" target="app/src/main/res/drawable-mdpi/notification_icon.png" />
  <resource-file src="resources/android/notification_icon/drawable-hdpi/notification_icon.png" target="app/src/main/res/drawable-hdpi/notification_icon.png" />
  <resource-file src="resources/android/notification_icon/drawable-xhdpi/notification_icon.png" target="app/src/main/res/drawable-xhdpi/notification_icon.png" />
  <resource-file src="resources/android/notification_icon/drawable-xxhdpi/notification_icon.png" target="app/src/main/res/drawable-xxhdpi/notification_icon.png" />
  <resource-file src="resources/android/notification_icon/drawable-xxxhdpi/notification_icon.png" target="app/src/main/res/drawable-xxxhdpi/notification_icon.png" />
</platform>

6) Ahora que tiene su icono en la aplicación como recurso dibujable, necesita forzar a su aplicación a usarlo. Independientemente de lo que esté escrito en el archivo Léame aquí, el descubrimiento automático del recurso dibujable llamado 'icono de notificación' no funcionó para mí. No estoy exactamente seguro de por qué, porque parece estar en el código base aquí: https://github.com/arnesson/cordova-plugin-firebase/blob/master/src/android/FirebasePluginMessagingService.java#L140 pero estoy adivinar que algo ha cambiado con el descubrimiento de recursos en las últimas versiones de Android.
7) Por eso, la única otra solución que podía usar era enviar el parámetro icon desde el backend al enviar una notificación push a firebase. Tenga en cuenta que su api probablemente esté experimentando algunos cambios porque tiene problemas para fusionar correctamente las partes notification y android de la carga útil. Por esa razón, debe agregar el parámetro de icono a la parte notification del json. El uso de parámetros específicos de Android no funcionará.

Por lo tanto, la carga útil de notificación que envía a firebase desde su backend debe tener un aspecto similar a esto: ESTA ES LA ÚNICA VERSIÓN QUE FUNCIONA

{
  notification: {
    body: 'Imma push your notification if you know what i mean!',
    icon: 'notification_icon',
  },
  data: { someExtraData: 'goes_here' }
}

Permítanme reiterar: EL USO DE PARÁMETROS ESPECÍFICOS DE ANDROID NO FUNCIONA CON FIREBASE A PARTIR DE JULIO DE 2018, A CONTINUACIÓN NO FUNCIONARÁ Y SU ICONO DE NOTIFICACIÓN NO CAMBIARÁ INDEPENDIENTEMENTE DE LO QUE DICE SU DOCUMENTACIÓN :

{
  notification: {
    body: 'Imma push your notification if you know what i mean!'
  },
  data: { someExtraData: 'goes_here_if_you_need_it' },
  android: { 
    icon: 'notification_icon'
  } 
}

8) Con todos los pasos completados, ahora está listo para probar su nuevo ícono. Sugiero encarecidamente probarlo dentro del emulador de Android: algunas de las máscaras de Android toman el control de la barra de notificaciones y usan el ícono de la aplicación independientemente de lo que establezca (es decir, MIUI de xiaomi). También he descubierto que a veces los iconos se almacenan en caché. Por esa razón, probarlo en un simulador en un AVD recién creado es su apuesta más segura. Elimine su aplicación manualmente entre las ejecuciones de prueba y reinicie el simulador / dispositivo para evitar problemas de almacenamiento en caché.

Espero que este largo artículo ayude a otros en el futuro, ya que la cantidad de obstáculos que uno tiene que atravesar para cambiar el ícono pequeño de 10x10 es simplemente demasiado alto ...

Comentario más útil

Pruebe si este código agregado a la etiqueta config.xml <platform name="android"> agregará el ícono como ícono de notificación predeterminado.

<config-file parent="/manifest/application/" target="app/src/main/AndroidManifest.xml">
    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon" />
</config-file>

Esto funciona para mí enviando por el panel de Firebase Cloud Messaging o el back-end sin un ícono en la carga útil.
Publique aquí los comentarios.
Si funciona, su tutorial agregado a este código ayudará a mucha gente y debería abrir un PR para agregarlo al README.

Todos 22 comentarios

Pruebe si este código agregado a la etiqueta config.xml <platform name="android"> agregará el ícono como ícono de notificación predeterminado.

<config-file parent="/manifest/application/" target="app/src/main/AndroidManifest.xml">
    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon" />
</config-file>

Esto funciona para mí enviando por el panel de Firebase Cloud Messaging o el back-end sin un ícono en la carga útil.
Publique aquí los comentarios.
Si funciona, su tutorial agregado a este código ayudará a mucha gente y debería abrir un PR para agregarlo al README.

¡¡Gracias @madsheep !! me salvaste la vida !!

Hola, gracias por el apoyo moral, y por darme la sensación de que no soy el único que terminó en este lío. Sin embargo, desafortunadamente, volví al paso previo 0, perdiendo cabello en el camino.

Cuando intento enviar la notificación a través del método http / post, obtengo errores de la API de firebase que indican que el json no es válido. Lo he intentado en ambos sentidos:

Esto es lo que obtengo cuando incluyo el ícono como message: { notification: { icon: 'notification_icon', ... }, ... }

Error code=400, message=Invalid JSON payload received. Unknown name "icon" at 'message.notification': Cannot find field., status=INVALID_ARGUMENT, details=[@type=type.googleapis.com/google.rpc.BadRequest, fieldViolations=[field=message.notification, description=Invalid JSON payload received. Unknown name "icon" at 'message.notification': Cannot find field.]]

Este es el mensaje que recibo cuando incluyo el ícono como message: { android: { icon: 'notification_icon' }, ... }

Error code=400, message=Invalid JSON payload received. Unknown name "icon" at 'message.android': Cannot find field., status=INVALID_ARGUMENT, details=[@type=type.googleapis.com/google.rpc.BadRequest, fieldViolations=[field=message.android, description=Invalid JSON payload received. Unknown name "icon" at 'message.android': Cannot find field.]]

pero tal vez estoy usando esto en el contexto incorrecto (nuestro código de backend en la nube envía una notificación a las aplicaciones cliente mediante la mensajería en la nube de Firebase).

esto funcionó bien para mí (envío notificaciones usando funciones de base de fuego):
const payload = { notification: { title: ........, body: ........., icon: 'notification_icon' } };

Gracias, eso resulta en el primero de los dos errores para mí. Estoy usando el servicio REST a través de una biblioteca de javascript / request y envío de acuerdo con el formato https://firebase.google.com/docs/cloud-messaging/js/first-message . Supongo que el formato de mensaje / notificación se describe en https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#Notification .

De hecho, cuando leo esto, esto sugiere que el ícono debería estar en message.android.notification.icon , es decir, un nivel más profundo.

Lo intenté, ¡y esto realmente funciona para mí! Así que supongo que depende del protocolo del servidor cómo se debe estructurar la carga útil ...

Gracias a todos por esta discusión. Finalmente ha resultado en que deje de tirarme de los pelos ...

cerrando como resuelto

@madsheep No está funcionando. Después de agregar 'ícono' debajo de la notificación en la función de nube, da el siguiente error:

{ Error: Invalid JSON payload received. Unknown name "icon" at 'message.notification': Cannot find field

errorInfo:
{código: 'mensajería / argumento inválido',
mensaje: 'Se recibió una carga útil JSON no válida. "Icono" de nombre desconocido en 'message.notification': No se puede encontrar el campo. ' },
codePrefix: 'mensajería'}

intente message.android.notification.icon lugar de message.notification.icon .

@madsheep @guilhermehtk ¡ Me funcionó! Gracias.

Pruebe si este código agregado a la etiqueta config.xml <platform name="android"> agregará el ícono como ícono de notificación predeterminado.

<config-file parent="/manifest/application/" target="app/src/main/AndroidManifest.xml">
    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon" />
</config-file>

Esto funciona para mí enviando por el panel de Firebase Cloud Messaging o el back-end sin un ícono en la carga útil.
Publique aquí los comentarios.
Si funciona, su tutorial agregado a este código ayudará a mucha gente y debería abrir un PR para agregarlo al README.

Usted acaba de hacer mi día,

si alguien se enfrenta a un problema en la construcción como

AAPT: error: prefijo independiente.

luego intente agregar el

xmlns: android = " http://schemas.android.com/apk/res/android "

el atributo debe agregarse a la raízetiqueta dentro del config.xml

¡Salvaste mi día!

Para cualquiera que enfrente este problema en 2019 con la compilación de Android 7.1.1, ¡parece que la carpeta de recursos ha cambiado!

Al verificar el estudio de Android y los archivos generados, esto es lo que funcionó para mí:

<resource-file src="resources/android/notification/notification_icon.png" target="app/src/main/res/drawable/notification_icon.png" />
<config-file parent="/manifest/application/" target="app/src/main/AndroidManifest.xml">
            <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon" />
</config-file>

La primera línea es la parte importante, ya que eso estuvo mal para mí.

@alarv El ícono no se muestra para algunos teléfonos Android, cualquier ayuda al respecto, por favor.

Hola @bioyeneye, ¿qué modelos? ¿Qué versión de Android están ejecutando? ¿Stock u otro?

@bioyeneye Tengo otra solución para Ionic 4 para que los iconos funcionen en todos los dispositivos Android.
No estoy usando un png para el icono sino XML. Estoy usando un gancho para incluir esto en los siguientes directorios:

'res/drawable-hdpi',
'res/drawable-mdpi',
'res/drawable-xhdpi',
'res/drawable-xxhdpi',
'res/drawable-xxxhdpi',
'res/mipmap-hdpi',
'res/mipmap-mdpi',
'res/mipmap-xhdpi',
'res/mipmap-xxhdpi',
'res/mipmap-xxxhdpi'

crear un ejemplo de archivo:
android_notification_resources.js

En este nuevo archivo de gancho, agregue:


// COMENZAR
const fs = require ("fs");
const ruta = require ("ruta");
const Q = require ("q");

var sourceDir = 'recursos / android / notification_icon'; // aquí es donde está tu icono
var platformDir = 'plataformas / android / app / src / main /';
var resourceDirs = [
'res / drawable-hdpi',
'res / drawable-mdpi',
'res / drawable-xhdpi',
'res / drawable-xxhdpi',
'res / drawable-xxxhdpi',
'res / mipmap-hdpi',
'res / mipmap-mdpi',
'res / mipmap-xhdpi',
'res / mipmap-xxhdpi',
'res / mipmap-xxxhdpi'
];

module.exports = function (ctx) {

if (ctx.opts.platforms.indexOf ('android') <0) {
regreso;
}

var diferido = Q.defer ();
var androidPlatformDir = path.join (ctx.opts.projectRoot, platformDir);
var customResourcesDir = path.join (ctx.opts.projectRoot, sourceDir);

función copy (src, dest) {
var diferido = Q.defer ();

fs.stat(src, function(err, stats) {
  if (err || !stats.isFile()) {
    return deferred.reject(err);
  }

  fs.stat(path.dirname(dest), function(err, stats) {
    if (err || !stats.isDirectory()) {
      return deferred.reject(err);
    }

    var rs = fs.createReadStream(src);

    rs.on('error', function(err) {
      console.error(err.stack);
      deferred.reject(err);
    });

    var ws = fs.createWriteStream(dest);

    ws.on('error', function(err) {
      console.error(err.stack);
      deferred.reject(err);
    });

    ws.on('close', function() {
      deferred.resolve();
    });

    rs.pipe(ws);
  });
});

return deferred.promise;

}

fs.stat (customResourcesDir, function (err, stats) {
if (err ||! stats.isDirectory ()) {
retorno diferido.resolve ();
}

fs.readdir(customResourcesDir, function(err, files) {
  var copies = [];

  for (var i in files) {
    for (var j in resourceDirs) {
      var filePath = path.join(ctx.opts.projectRoot, sourceDir, files[i]);
      var destPath = path.join(androidPlatformDir, resourceDirs[j], files[i]);

      copies.push([filePath, destPath]);
    }
  }

  copies.map(function(args) {
    return copy.apply(copy, args);
  });

  Q.all(copies).then(function(r) {
    deferred.resolve();
  }, function(err) {
    console.error(err.stack);
    deferred.reject(err);
  });
});

});

retorno diferido.promise;
}
// FIN


en su config.xml agregue esta línea para incluir su gancho:

Lo que hará el gancho es copiar su icono de su carpeta de recursos y agregarlo en diferentes carpetas de elementos de diseño. Hice esto para asegurarme de que funciona para todos los dispositivos. Hasta ahora tan bueno.

¡Déjame saber si te funcionó! salud

@RobinGiel Gracias, estoy usando ionic 3, ¿funcionará?

Hola @Flucadetena
Android 9
Plataformas Cordova: android 7.1.1

@bioyeneye También estoy usando ionic 3. Lo comprobaré todo y te lo haré saber. ;)

@bioyeneye Sí, tendrá que modificar algunas líneas del gancho.

var sourceDir = 'recursos / android / notification_icon';
var platformDir = 'plataformas / android';

y quizás en lugar de usar const Q = require ("q"); elimine esa línea y úsela aquí ... ejemplo:

module.exports = function (ctx) {

if (ctx.opts.platforms.indexOf ('android') <0) {
regreso;
}

var Q = ctx.requireCordovaModule ('q'); // úsalo aquí
var diferido = Q.defer ();
var androidPlatformDir = path.join (ctx.opts.projectRoot, platformDir);
var customResourcesDir = path.join (ctx.opts.projectRoot, sourceDir);


Agregue el config.xml llamando al mismo ejemplo de gancho before_build y before_run:

<hook type="before_run"         src="hooks/android_notification_resources.js" />
<hook type="before_build"       src="hooks/android_notification_resources.js" />

Pruebe si este código agregado a la etiqueta config.xml <platform name="android"> agregará el ícono como ícono de notificación predeterminado.

<config-file parent="/manifest/application/" target="app/src/main/AndroidManifest.xml">
    <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/notification_icon" />
</config-file>

Esto funciona para mí enviando por el panel de Firebase Cloud Messaging o el back-end sin un ícono en la carga útil.
Publique aquí los comentarios.
Si funciona, su tutorial agregado a este código ayudará a mucha gente y debería abrir un PR para agregarlo al README.

Usted acaba de hacer mi día,

si alguien se enfrenta a un problema en la construcción como

AAPT: error: prefijo independiente.

luego intente agregar el

xmlns: android = " http://schemas.android.com/apk/res/android "

El atributo debe agregarse a la etiqueta raíz dentro del config.xml

Esto funciona para mí, pero el icono parece ser increíblemente pequeño, ¿cuál es el tamaño adecuado del archivo que deberíamos usar?

Editar: agregué un 256x256 pero todavía muestra un pequeño punto en la barra de estado. arrastrar la barra de estado hacia la parte inferior muestra una un poco más grande

ES

¡¡Eres mi salvavidas !! ¡¡¡Gracias!!!
Notas:
Agrego color: '# e50012' en la sección de notificaciones para cambiar el color del ícono (cámbielo a su color).
ex:
{
"nombre": "mi_notificación",
"notificación": {
"body": "Cuerpo de notificación",
"title": "Título de la notificación",
"color": "# e50012"
},
"datos":{ ... }
}

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

eilian92 picture eilian92  ·  4Comentarios

JonSmart picture JonSmart  ·  3Comentarios

chrissterling picture chrissterling  ·  3Comentarios

ulisesvera picture ulisesvera  ·  5Comentarios

stephan-nordnes-eriksen picture stephan-nordnes-eriksen  ·  5Comentarios