15

随着新的更新,现在将使用 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"}]}

注意:我浏览了他们的文档并修改了代码要点,使其只有正文和标题。即使那样它也不起作用。

4

7 回答 7

16

你可以使用这个完整的代码

<?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)调用。

于 2016-10-26T07:27:15.983 回答
9

我试过这个并且工作:

<?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"}]}
于 2016-09-09T03:06:10.663 回答
3

为了使用 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

于 2016-05-27T12:56:40.173 回答
2

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

由于“通知”字段是RemoteMessage.Notification的 JSON 表示。RemoteMessage.getNotification()如果您在“通知”字段中设置通知类的任何预定义字段,则在客户端成功解析 JSON,并且您有一个可以调用getBody()//的非空值getTopic()getIcon()

但是,如果您没有在“通知”json 字段中设置 Notification 类的任何字段,则解析到类会失败,并且您将获得 null 值RemoteMessage.getNotification()

因此,以下三个 JSON 中的任何一个都是用于推送 a 的有效 POST 主体RemoteMessage.Notification(除了 Andrea 在之前的回答中共享的两个示例),即这三个不会导致上述 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"
        }
    }
    
于 2016-06-23T14:14:10.017 回答
2

从 php gist 中,您正在发送仅数据消息。您的接收者期待一条通知消息,因此当您从远程消息中收到通知时,它将为空,从而在您调用 getBody 时导致 NPE。

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

于 2016-05-21T00:29:10.447 回答
1

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 存储在令牌变量中

于 2017-03-17T13:21:58.613 回答
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;
}
?>
于 2017-04-17T13:42:37.763 回答