Enviar mensajes de FCM del lado del servidor a un dispositivo Android

Con la nueva actualización, ahora se usará FCM.

Probé la aplicación de muestra de git y está funcionando todo bien. Puedo enviar notificaciones desde la consola.

Pero quiero enviar la notificación desde el servidor después de que se desencadena un determinado evento. Seguí el mismo enfoque como en GCM pero no funciona.

05-20 20:40:58.941 30132-30919/com.google.firebase.quickstart.fcm E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1 Process: com.google.firebase.quickstart.fcm, PID: 30132 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.messaging.RemoteMessage$Notification.getBody()' on a null object reference at com.google.firebase.quickstart.fcm.MyFirebaseMessagingService.onMessageReceived(MyFirebaseMessagingService.java:53) at com.google.firebase.messaging.FirebaseMessagingService.zzo(Unknown Source) at com.google.firebase.messaging.FirebaseMessagingService.zzn(Unknown Source) at com.google.firebase.messaging.FirebaseMessagingService.zzm(Unknown Source) at com.google.firebase.iid.zzb$2.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) 05-20 20:40:59.118 30132-30279/com.google.firebase.quickstart.fcm E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb9e83390 

Estoy siguiendo este script PHP para enviar la notificación. Si trato de ejecutar el script, obtengo el siguiente resultado.

 {"multicast_id":4679427854122301046,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1463757518309261%31bd1c96f9fd7ecd"}]} 

NOTA: Revisé sus documentos y modifiqué el código, es esencial tener solo cuerpo y título. Incluso entonces no está funcionando.

Puedes usar este código completo

  $id, 'notification' => array ( "body" => $mess, "title" => "Title", "icon" => "myicon" ) ); $fields = json_encode ( $fields ); $headers = array ( 'Authorization: key=' . "AIzaSyA9vpL9OuX6moOYw-4n3YTSXpoSGQVGnyM", 'Content-Type: application/json' ); $ch = curl_init (); curl_setopt ( $ch, CURLOPT_URL, $url ); curl_setopt ( $ch, CURLOPT_POST, true ); curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers ); curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt ( $ch, CURLOPT_POSTFIELDS, $fields ); $result = curl_exec ( $ch ); curl_close ( $ch ); } ?> 

Pase el mensaje y la identificación del token como parámetro a la sendFCM($mess,$id) .

Intenté esto y trabajé:

  

Este es el resultado:

 {"multicast_id":4913280949692448120,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1473389987003950%ab9a0bb6ab9a0bb6"}]} 

Para recibir la notificación utilizando remoteMessage.getNotification (). GetBody () , debe usar el conjunto de opciones de clave predefinido para la notificación.

En este caso, “notificación” es la palabra clave.

La respuesta JSON debe formatearse así.

  { "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", "notification" : { "body" : "great match!", "title" : "Portugal vs. Denmark", "icon" : "myicon" } } 

También puede enviar notificación y carga útil de datos en la misma respuesta JSON

  { "to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...", "notification" : { "body" : "great match!", "title" : "Portugal vs. Denmark", "icon" : "myicon" }, "data" : { "Nick" : "Mario", "Room" : "PortugalVSDenmark" } } 

mira esto: https://firebase.google.com/docs/cloud-messaging/concept-options#messages-with-both-notification-and-data-payloads

Desde el punto de vista php, está enviando un mensaje de solo datos. Su receptor espera un mensaje de notificación para que cuando reciba la notificación del mensaje remoto sea nulo, lo que resultará en un NPE cuando llame a getBody.

Envíe un mensaje de notificación y debería funcionar como se esperaba. Consulte los requisitos de mensajes de notificación aquí: https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support

Estaba enfrentando el mismo problema y después de pasar algún tiempo tratando de descubrir la causa, mi observación fue:

Dado que el campo “notificación” es la representación JSON de RemoteMessage.Notification . Si configura cualquiera de los campos predefinidos de la clase de Notificación en el campo “notificación”, en el lado del cliente, el JSON se analiza correctamente y tiene un valor no nulo para RemoteMessage.getNotification() en el que puede llamar al getBody() / getTopic() / getIcon() .

Pero si no establece ningún campo de la clase de notificación en el campo json “notificación”, el análisis en clase falla y tendrá un valor nulo para RemoteMessage.getNotification()

Por lo tanto, cualquiera de los siguientes tres JSON es un cuerpo de POST válido para RemoteMessage.Notification un RemoteMessage.Notification (además de los dos ejemplos compartidos por Andrea en la respuesta anterior), es decir, estos tres no causarán el NPE anterior.

  { "to" : "<>", "notification" : { "body" : "Notification Message Body" } } { "to" : "<>", "notification" : { "title" : "Notification Title" } } { "to" : "<>", "notification" : { "icon" : "Notification icon" } } 

Y ninguno de los siguientes tres son válidos para presionar un RemoteMessage.Notification –

  1. No tiene el campo “notificación”

     { "to" : "<>" } 
  2. El campo “notificación” es un json vacío

     { "to" : "<>", "notification" : { } } 
  3. El campo “notificación” tiene algunos pares de valores clave, pero ninguno de los campos definidos en la clase RemoteMessage.Notification

     { "to" : "<>", "notification" : { "messageText" : "Notification Message Text", "messageBody" : "Notification Message Body" } } 
 function send_fcm($tokens,$message) { $url = 'https://fcm.googleapis.com/fcm/send'; $priority="high"; $fields = array( 'registration_ids' =>$tokens, 'data' =>$message ); $headers = array( 'Authorization:key=your key', 'Content-Type: application/json' ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields)); echo json_encode($fields); $result = curl_exec($ch); curl_error($ch); if ($result === FALSE) { die('Curl failed: ' . curl_error($ch)); } curl_close($ch); return $result; } 

Pruebe con este código a continuación, esto dará notificación push para Android desde el lado del servidor php y puede obtener el token del dispositivo desde Android que necesita pasar de forma dinámica para obtener notificación de empuje para más dispositivos Android.

  array($devicetoken));//get the device token from Android $headers = array( 'Authorization: key=' . $api_key,'Content-Type: application/json'); $ch = curl_init(); curl_setopt( $ch, CURLOPT_URL, $url ); curl_setopt( $ch, CURLOPT_POST, true ); curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($fields) ); $result = curl_exec($ch); if(curl_errno($ch)){ return 'Curl error: ' . curl_error($ch); } curl_close($ch); $cur_message=json_decode($result); if($cur_message->success==1) return true; else return false; } ?>