registro notification new firebaseinstanceidservice fcm data android firebase-cloud-messaging device-admin

notification - Mensaje de Firebase con dispositivo de alta prioridad sin activación de Doze Android 6+



notification payload (4)

Después de luchar con un problema similar, logré que funcionara.

Envío los siguientes datos json a través del cartero:

{ "data": { "body": "Test body from curl" }, "registration_ids": ["Token"], "webpush": { "headers": { "Urgency": "high" } }, "android": { "priority": "high" }, "priority": 10 }

Parece que la última "priority":10 es lo que me lo está arreglando.

No pude encontrar ninguna referencia a esto en la documentación de Firebase, pero en la documentación obsoleta de GCM se usa. https://developers.google.com/cloud-messaging/concept-options

He migrado mi proyecto de usar GCM para usar Firebase. La notificación de inserción llega a través de ok cuando el dispositivo está despierto o ha estado dormido recientemente, pero si dejo el dispositivo por una hora, no se envía ninguna pulsación hasta que el dispositivo se active.

Los documentos de Android dicen que si necesita activar un dispositivo para enviar un mensaje, use FireBase con la prioridad establecida en alta. También dice que las aplicaciones de administración de dispositivos no están sujetas a restricciones Doze, mi aplicación es una aplicación de administración de dispositivos.

Pensé en mencionar que cuando migre el proyecto de GCM a FCM, solo especifiqué el nombre del paquete en la consola de base de fuego y no la huella digital.

Lo que he intentado.

  1. Establecer prioridad a alta

    { "time_to_live": 300000, "delay_while_idle": false, "android": { "priority": "high" }, "data": { "message": "PING_DEVICE", "time": "21/01/2018 16:20:28", "pushguid": "10062" }, "registration_ids": [ "eOMT........" ] }

    Se establece el tiempo de vida para que el mensaje llegue finalmente. delay_while_idle se establece en falso, FCM ignora esto después de septiembre de 2016.

  2. Las aplicaciones de administración de dispositivos no están sujetas a Doze, la mía es una aplicación de administración de dispositivos, pero también he agregado explícitamente la aplicación a la lista blanca de Doze que se encuentra en Configuración -> Batería -> Optimización. Esto se hizo manualmente a través de la aplicación de configuración y NO programáticamente en el código.

He dejado mi dispositivo para ir a dormir durante 3 horas y no he recibido ninguna pulsación. También he usado adb para poner el dispositivo en Doze. Cuando adb pone el dispositivo en Doze, no se recibe ningún push, cuando adb saca el dispositivo de Doze, el push llega.

Más pensamientos que no he probado.

Mis empujones son mensajes de datos. Esto se debe a que no quiero que el impulso llegue a la barra de notificaciones en el dispositivo y que el usuario haga clic para ejecutar la funcionalidad. El usuario no tiene interacción con la aplicación de administración del dispositivo. Así que un mensaje de datos es manejado por

onMessageReceived(RemoteMessage remoteMessage)

Creo que los mensajes de notificación activan el dispositivo, que es lo que necesito, pero quiero que la aplicación se encargue de la inserción, no del usuario. ¿Podría tener mensajes que sean tanto de notificación como de datos, pero que tengan onMessageRecievied que maneje la funcionalidad?

¿Alguien ha experimentado algo similar o tiene alguna solución a esto?

[EDIT1] Encontré el siguiente enlace a continuación que dice que puede enviar un mensaje que es a la vez notificación y datos, pero si la aplicación está en segundo plano, la notificación se muestra pero los datos solo se ejecutan cuando el usuario hace clic en la notificación. Esto no es lo que quiero, ya que me gustaría que los datos se ejecuten en onMessageRecived de inmediato.

notificación con datos

[EDIT2] He añadido el siguiente código y permiso a la aplicación. La aplicación ahora le pide al usuario que incluya la aplicación en la lista blanca de Doze, así que hice clic en sí. Entonces a través de adb puse el dispositivo en Doze y envié un empujón. No llegó nada hasta que saqué el dispositivo de modo inactivo. Así que, desafortunadamente, esto no funciona.

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { Intent intent = new Intent(); String packageName = getPackageName(); PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); if (!pm.isIgnoringBatteryOptimizations(packageName)) { intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS); intent.setData(Uri.parse("package:" + packageName)); startActivity(intent); } } <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

[EDIT3]

He realizado pruebas adicionales para tratar de aislar el problema y sacar el código de mi aplicación web de la ecuación. Puse el dispositivo en Doze a través de adb y la consola FireBase usada para enviar el envío en su lugar. La inserción se realizó correctamente. Esto me dice que hay un problema con el código de mi aplicación web que envía toda la información de inserción al punto final de fcm. Obtendré el código esta noche y lo publicaré más tarde.

[EDIT4] Acabo de hacer algunas pruebas más. Coloqué el dispositivo en una posición de inactividad y luego usé la consola FireBase para enviar un mensaje de datos con 2 pares clave-valor. Cuando el dispositivo está en Doze y la aplicación está en primer plano (en la pantalla), el mensaje llega y OnMessageReceived se ejecuta. Esto es genial. Sin embargo, si la aplicación está en el BG, solo se muestra una notificación. Entiendo que desde los documentos, los mensajes de datos se envían a la actividad del iniciador a través de un Intent, pero mi aplicación de iniciador no maneja los empujes. La clase que maneja los empujes se llama MyAndroidFirebaseMsgService y extiende FirebaseMessagingService.

¿Tengo que dirigir la intención a esta clase en caso de que la aplicación esté en el BG? Parece un poco ansioso por tener que hacer esto. Nunca fue el caso en GCM.

Además, no quiero que la aplicación se inicie desde un momento dado, ya que esto es muy invasivo, ya que el usuario del dispositivo podría estar usando una aplicación diferente. Mi aplicación también es una aplicación de administración de dispositivos, por lo que el 99% del tiempo no hay interacción del usuario, es solo un cliente que ejecuta las políticas en el dispositivo.

[editar5]

internal static void SendNotification ( Dictionary<string, string> nameValues , List<string> theregIDs , string sPushName) { string stringregIds = string.Join("/",/"", theregIDs) ; JavaScriptSerializer js = new JavaScriptSerializer(); string keyValueJson = js.Serialize(nameValues); string TIME_TO_LIVE = "604800"; string DELAY_WHILE_IDLE = "false"; string ENDPOINTADDRESS = @"https://fcm.googleapis.com/fcm/send"; postData = String.Concat("{/"time_to_live/":", TIME_TO_LIVE, ",/"delay_while_idle/": ", DELAY_WHILE_IDLE, ", /"android/":{/"priority/":/"high/" } ,/"data/": { /"message/" : " + "/"" + sPushName + "/",/"time/": " + "/"" + System.DateTime.Now.ToString() + "/"" , keyValueJson , "},/"registration_ids/":[/"" + stringregIds + "/"]}"); WebRequest myWebRequest = null; WebResponse myWebResponse = null; try { myWebRequest = WebRequest.Create(ENDPOINTADDRESS); myWebRequest.Method = "post"; myWebRequest.ContentType = "application/json"; // myWebRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8"; myWebRequest.Headers.Add("Authorization: key=" + Our_Api_Key); myWebRequest.Headers.Add("Sender:id=" + Our_Sender_Id); Byte[] BA = Encoding.UTF8.GetBytes(postData); myWebRequest.ContentLength = BA.Length; using (Stream dataStreamOut = myWebRequest.GetRequestStream()) { dataStreamOut.Write(BA, 0, BA.Length); } using (myWebResponse = myWebRequest.GetResponse()) { using (Stream dataStream = myWebResponse.GetResponseStream()) { using (StreamReader tReader = new StreamReader(dataStream)) { strServerResponse = tReader.ReadToEnd(); } } } } catch (WebException ex) { } }//

Gracias


Mientras trabajo en una aplicación, también estoy atascado en este punto. Luego encontré un problema al respecto en Github, que resolvió mi problema. Es decir,

En los dispositivos que ejecutan Android 6.0+, el modo Doze termina todas las conexiones de fondo cuando el teléfono está inactivo y no se está cargando, incluida la conexión de fondo a Pushy.

Tan pronto como el usuario mueva o despierte el dispositivo, se restaurarán las conexiones en segundo plano y las notificaciones pendientes se enviarán en segundos, siempre que aún no hayan expirado.

Para enviar notificaciones a los dispositivos en el modo Doze, su aplicación puede declarar el permiso REQUEST_IGNORE_BATTERY_OPTIMIZATIONS en su AndroidManifest.xml y mostrar un cuadro de diálogo del sistema que solicita a los usuarios que incluyan en la lista blanca las optimizaciones de la batería sin salir de la aplicación.

Esto mantendrá efectivamente la conexión en segundo plano a Pushy activa y los dispositivos podrán recibir notificaciones incluso en el modo Doze.

Puede consultar este problema aquí https://github.com/ToothlessGear/node-gcm/issues/231

Espero que te ayude!


No hay nada que puedas hacer.

Este es un problema conocido causado por una optimización de la batería implementada por algunos OEM (como Meizu o Asus). Cuando se quita una aplicación en el conmutador de aplicaciones, la aplicación se trata como si se hubiera detenido forzosamente, que no es el comportamiento predeterminado de Android. El desafortunado efecto secundario de esto es que puede hacer que el servicio FCM para su aplicación deje de ejecutarse. Se puede producir un efecto similar en los mensajes de alta prioridad en el modo Doze.

El equipo de Firebase está trabajando para mejorar este comportamiento desde su extremo, pero la solución real debe provenir del lado del OEM.

Una forma de verificar si su aplicación se ve afectada por la función de administración de batería de cualquier OEM es la siguiente:

1) Conecte el dispositivo OEM a adb

2) Ejecuta tu aplicación en el dispositivo

3) Deslice la aplicación lejos de la pantalla reciente en el dispositivo

4) Ejecute el comando: paquete adb shell dumpsys MY-PACKAGE | grep se detuvo

Si se muestra detenido = verdadero, es seguro asumir que el OEM tiene tal mecanismo y que su aplicación se ve afectada por el mismo.


Parece que no es posible dar prioridad alta al enviar solo el campo de datos sin notificación. Aquí está la cita de la documentation :

Los mensajes de alta prioridad generalmente deben resultar en la interacción del usuario con su aplicación o sus notificaciones. Si FCM detecta un patrón en el que no lo hacen, es posible que se desactiven los mensajes.