【问题标题】:Send FCM messages from server side to android device从服务器端向安卓设备发送 FCM 消息
【发布时间】:2016-09-17 22:19:35
【问题描述】:

随着新的更新,现在将使用 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 并修改了代码要点,使其只有正文和标题。即使那样它也不起作用。

【问题讨论】:

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


【解决方案1】:

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

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

【讨论】:

  • 是的。当我尝试通过remoteMessage.getData().get("body"); 获取数据时,我正在获取文本。知道如何在那里创建通知吗?该文档指定了所需的字段,但我如何在那里创建notification
  • 数据对象和通知对象是同级的,因此您可以使用文档中的通知字段在您拥有数据对象的同一级别创建通知对象。
  • 我试试看。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    因为“通知”字段是 RemoteMessage.Notification 的 JSON 表示形式。 如果您在“通知”字段中设置通知类的任何预定义字段,则在客户端成功解析 JSON,并且您可以在 RemoteMessage.getNotification() 上获得一个非空值拨打 getBody() / getTopic() / getIcon()

    但是如果你没有在“notification”json字段中设置Notification类的任何字段,解析到类会失败,RemoteMessage.getNotification()

    因此,以下三个 JSON 中的任何一个都是用于推送 RemoteMessage.Notification 的有效 POST 正文(除了 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"
          }
      }
      

    【讨论】:

      【解决方案4】:

      我试过这个并且成功了:

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

      【讨论】:

      • 如果我想将推送消息发送给许多人,我认为上述脚本仅适用于一个用户......
      • 如何将此结果存储在变量中?
      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          试试下面的代码,这将从 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;
          }
          ?>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-02-20
            • 2011-10-14
            • 2017-01-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多