Отправлять сообщения FCM с серверной части на устройство Android

С новым обновлением FCM теперь будет использоваться.

Я попробовал пример приложения от git, и он работает отлично. Я могу отправлять уведомления с консоли.

Но я хочу отправить уведомление с сервера после запуска определенного события. Я следовал тому же подходу, что и в GCM, но он не работает.

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 

Следуйте этому скрипту PHP, чтобы отправить уведомление. Если я попытаюсь выполнить скрипт, я получаю следующий результат.

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

ПРИМЕЧАНИЕ. Я просмотрел их документы и изменил код, чтобы иметь только тело и название. Даже тогда это не работает.

Вы можете использовать этот полный код

 <?php function sendFCM($mess,$id) { $url = 'https://fcm.googleapis.com/fcm/send'; $fields = array ( 'to' => $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 ); } ?> 

Передайте сообщение и идентификатор токена в качестве параметра для sendFCM($mess,$id) .

Я попробовал это и работал:

 <?php $ch = curl_init("https://fcm.googleapis.com/fcm/send"); $header=array('Content-Type: application/json', "Authorization: key=GoGdfsflknEFñslknaglksjfnklj"); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false ); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, "{ \"notification\": { \"title\": \"Test desde curl\", \"text\": \"Otra prueba\" }, \"to\" : \"SGferg-qWEFWbI:dflñkndfakllvakrgalkgjdgjslfkgjdglksdjflksjglkjlkñerhTHDFSHFZDHzdfakjsdhskjhgkjashfdasjdkf\"}"); curl_exec($ch); curl_close($ch); ?> 

Это результат:

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

Чтобы получить уведомление, используя remoteMessage.getNotification (). GetBody () , вы должны использовать предопределенный набор параметров ключа для уведомления.

В этом случае ключевым словом является «уведомление» .

Ответ JSON должен быть отформатирован следующим образом.

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

Вы также можете отправлять уведомления и данные в один и тот же ответ JSON

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

см. это: https://firebase.google.com/docs/cloud-messaging/concept-options#messages-with-both-notification-and-data-payloads

Из php gist вы отправляете сообщение только с данными. Ваш приемник ожидает сообщение с уведомлением, поэтому, когда вы получите уведомление от удаленного сообщения, оно будет null, в результате чего NPE вы вызовете getBody.

Отправьте сообщение с уведомлением, и оно должно работать должным образом. Требования к уведомлению см. Здесь: https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support

Я столкнулся с той же проблемой, и, проведя некоторое время, пытаясь выяснить причину, мое наблюдение было –

Поскольку поле «уведомление» представляет собой JSON-представление RemoteMessage.Notification . Если вы установите любое из предопределенных полей класса Notification в поле «уведомление», на стороне клиента JSON успешно разобран и у вас есть ненулевое значение для RemoteMessage.getNotification() на котором вы можете вызвать getBody() / getTopic() / getIcon() .

Но если вы не установите какое-либо поле класса Notification в поле «уведомление» json, синтаксический разбор класса будет RemoteMessage.getNotification() и у вас будет RemoteMessage.getNotification() значение для RemoteMessage.getNotification()

Таким образом, любой из следующих трех JSON – это действительное тело POST для нажатия RemoteMessage.Notification (в дополнение к двум примерам, разделяемым Andrea в более раннем ответе), т. RemoteMessage.Notification Эти три не вызовут вышеуказанный NPE

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

И ни один из следующих трех действителен для нажатия RemoteMessage.Notification –

  1. Не имеет поля «уведомление»

     { "to" : "<<FIREBASE_INSTANCE_ID>>" } 
  2. Поле «уведомление» – пустой json

     { "to" : "<<FIREBASE_INSTANCE_ID>>", "notification" : { } } 
  3. В поле «уведомление» есть несколько пар значений ключа, но ни одно из полей, определенных в классе RemoteMessage.Notification

     { "to" : "<<FIREBASE_INSTANCE_ID>>", "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; } 

Попробуйте этот ниже код, это даст push-уведомление для Android со стороны php-сервера, и вы можете получить токен устройства от android, который вам нужно пройти динамически, чтобы получить push-уведомление для большего количества устройств Android.

 <?php function sendmessage_android($devicetoken,$message){ $api_key = 'AIzaSyCtDch9K3ZqGF_SSLYCz4JjMS4-fkJuW';//get the api key from FCM backend $url = 'https://fcm.googleapis.com/fcm/send'; $fields = array('registration_ids' => 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; } ?>