从服务器端向Android设备发送FCM消息

时间:2016-05-20 15:23:55

标签: php android google-cloud-messaging firebase-cloud-messaging

通过新的更新,现在将使用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 Script发送通知。 如果我尝试执行脚本,我会得到以下结果。

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

注意:我经历了他们的docs并修改了代码是gist只有身体和标题。即便如此,它也无法正常工作。

7 个答案:

答案 0 :(得分:15)

您可以使用此完整代码

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

?>

将消息和令牌ID作为参数传递给sendFCM($mess,$id)调用。

答案 1 :(得分:7)

我试过这个并且工作了:

<?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"}]}

答案 2 :(得分:3)

要使用 remoteMessage.getNotification()。getBody() 接收通知,您必须使用预定义的密钥选项集进行通知。

在这种情况下,&#34;通知&#34; 是关键词。

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

答案 3 :(得分:2)

从php gist,您只发送一条数据消息。您的接收方期望收到通知消息,因此当您从远程消息收到通知时,它将为空,从而在您调用getBody时产生NPE。

发送通知消息,它​​应该按预期工作。请在此处查看通知消息要求 https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support

答案 4 :(得分:2)

我遇到了同样的问题,在花了一些时间试图找出原因之后,我的观察是 -

自&#34;通知&#34; field是RemoteMessage.Notification的JSON表示。 如果您在&#34;通知&#34;中设置了通知类的任何预定义字段。字段,在客户端,JSON已成功解析,并且您具有 RemoteMessage.getNotification() 的非空值,您可以在其上调用 getBody() / getTopic() / getIcon()

但是,如果你没有在&#34;通知&#34;中设置通知类的任何字段。 json字段,对类的解析失败, RemoteMessage.getNotification()

的值为null

因此,以下三个JSON中的任何一个都是一个有效的POST主体,用于推送 RemoteMessage.Notification (除了Andrea在之前的回答中分享的两个示例),即这三个赢得& #39; t导致上述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. 没有&#34;通知&#34;字段

    {
      "to" : "<<FIREBASE_INSTANCE_ID>>"
    }
    
  2. &#34;通知&#34; field是一个空的json

    {
      "to" : "<<FIREBASE_INSTANCE_ID>>",
      "notification" : {
      }
    }
    
  3. &#34;通知&#34; field有一些键值对,但没有在RemoteMessage.Notification类

    中定义的字段
    {
        "to" : "<<FIREBASE_INSTANCE_ID>>",
        "notification" : {
            "messageText" : "Notification Message Text",
            "messageBody" : "Notification Message Body"
        }
    }
    

答案 5 :(得分:0)

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

以数组格式

将设备ID存储在令牌变量中

答案 6 :(得分:0)

尝试以下代码,这将从php服务器端为Android提供推送通知,你可以从Android获取设备令牌,你需要动态传递以获得更多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;
}
?>