Send FCM messages from server side to android devi

2019-01-11 14:00发布

With the new update, FCM is now going to be used.

I tried the sample app from git and it's working all fine. I can send notifications from the console.

But I want to send the notification from the server after a certain event is triggered. I followed the same approach like in GCM but it's not working.

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

Am following this PHP Script to send the notification. If I try to execute the script, I get the following result.

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

NOTE : I went through their docs and modified the code is gist to have only body and title. Even then it's not working.

7条回答
smile是对你的礼貌
2楼-- · 2019-01-11 14:25

I was facing the same issue and after spending some time trying to find out the cause , my observation was --

Since the "notification" field is JSON representation of the RemoteMessage.Notification . If you set any of the predefined fields of the Notification class in the "notification" field , on client side the JSON is successfully parsed and you have a non-null value for RemoteMessage.getNotification() on which you can call the getBody() / getTopic() / getIcon().

But if you don't set any field of the Notification class in the "notification" json field, the parsing to class fails and you will have a null value for RemoteMessage.getNotification()

So, any of the following three JSONs is a valid POST body for pushing a RemoteMessage.Notification ( in addition to the two examples shared by Andrea in earlier answer ) , i.e. these three won't cause the above 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"
      }
    }

And none of the following three are valid for pushing a RemoteMessage.Notification -

  1. Doesn't have the "notification" field

    {
      "to" : "<<FIREBASE_INSTANCE_ID>>"
    }
    
  2. "notification" field is an empty json

    {
      "to" : "<<FIREBASE_INSTANCE_ID>>",
      "notification" : {
      }
    }
    
  3. "notification" field has some key value pairs , but none of the fields defined in RemoteMessage.Notification class

    {
        "to" : "<<FIREBASE_INSTANCE_ID>>",
        "notification" : {
            "messageText" : "Notification Message Text",
            "messageBody" : "Notification Message Body"
        }
    }
    
查看更多
再贱就再见
3楼-- · 2019-01-11 14:26

You can use this complete code

<?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 );
}

?>

Pass message and token id as a parameter to the sendFCM($mess,$id) call.

查看更多
看我几分像从前
4楼-- · 2019-01-11 14:29

From the php gist you are sending a data only message. Your receiver is expecting a notification message so when you get the notification from the remote message it will be null, resulting in a NPE when you call getBody.

Send a notification message and it should work as expected. See notification message requirements here: https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support

查看更多
5楼-- · 2019-01-11 14:29

Try this below code this will give push notication for Android from php server side and you can get the device token from android you need pass dynamically to get push notication for more android device.

<?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;
}
?>
查看更多
神经病院院长
6楼-- · 2019-01-11 14:42

I tried this and worked:

<?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);
?>

This is the result:

{"multicast_id":4913280949692448120,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1473389987003950%ab9a0bb6ab9a0bb6"}]}
查看更多
你好瞎i
7楼-- · 2019-01-11 14:42

In order to receive the notification using remoteMessage.getNotification().getBody(), you have to use the predefined set of key option for notification.

In this case, "notification" is the key word.

The JSON response has to be formatted like this.

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

You can also send notification and data payload in the same JSON response

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

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

查看更多
登录 后发表回答