【问题标题】:How to send push notifications to multiple devices using php script using FCM?如何使用 FCM 使用 php 脚本向多个设备发送推送通知?
【发布时间】:2017-09-15 14:08:06
【问题描述】:

我是使用 FCM 从 php 向 Android 设备推送通知的新手。从 android 端,我生成了 FCM reg_id 并通过 php 脚本将其发送并存储到 mysql 数据库中。现在,我想同时从 php 脚本向多个 android 设备发送通知。

这是发送推送通知时使用的 php 脚本:

1.firebase.php (reference link)

 <?php

class Firebase {

// sending push message to single user by firebase reg id
public function send($to, $message) {
    $fields = array(
        'to' => $to,
        'data' => $message,
    );
    return $this->sendPushNotification($fields);
}

// sending push message to multiple users by firebase registration ids
public function sendMultiple($registration_ids, $message) {
    $fields = array(
        'registration_ids' => $registration_ids,
        'data' => $message,
    );

    return $this->sendPushNotification($fields);
}

// function makes curl request to firebase servers
private function sendPushNotification($fields) {
    
    require_once('config.php');

    // Set POST variables
    $url = 'https://fcm.googleapis.com/fcm/send';

    $headers = array(
        'Authorization: key=' . FIREBASE_API_KEY,
        'Content-Type: application/json'
    );
    // Open connection
    $ch = curl_init();

    // Set the url, number of POST vars, POST data
    curl_setopt($ch, CURLOPT_URL, $url);

    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // Disabling SSL Certificate support temporarly
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

    // Execute post
    $result = curl_exec($ch);
    // echo "Result".$result;
    if ($result === FALSE) {
        die('Curl failed: ' . curl_error($ch));
    }

    // Close connection
    curl_close($ch);

    return $result;
   }
 }

?>

2.push.php : (reference link)

<?php

class Push {

// push message title
private $title;
private $message;
private $image;
// push message payload
private $data;
// flag indicating whether to show the push
// notification or not
// this flag will be useful when perform some opertation
// in background when push is recevied
private $is_background;

function __construct() {
    
}

public function setTitle($title) {
    $this->title = $title;
}

public function setMessage($message) {
    $this->message = $message;
}

public function setImage($imageUrl) {
    $this->image = $imageUrl;
}

public function setPayload($data) {
    $this->data = $data;
}

public function setIsBackground($is_background) {
    $this->is_background = $is_background;
}

public function getPush() {
    $res = array();
    $res['data']['title'] = $this->title;
    $res['data']['is_background'] = $this->is_background;
    $res['data']['message'] = $this->message;
    $res['data']['timestamp'] = date('Y-m-d G:i:s');
    return $res;
}

}

3.test.php

 <?php
include_once('config.php');
require_once('DB_Functions.php');
require_once('firebase.php');
require_once('push.php');



$db = new DB_Functions();
$firebase = new Firebase();
$push = new Push();

if(isset($_POST['send']))
{
    // $sendvalue = $_POST['send'];
        ChromePhp::log('send it '.$_POST['send']." user 
category:".$_POST['user_category']." Title : ".$_POST['message_title']." Message : ".$_POST['message_to_send']);

        $ucategory = $_POST['user_category'];
        ChromePhp::log('U category '.$ucategory);

        // notification title
        $messageTitle = isset($_POST['message_title']) ? $_POST['message_title'] : '';
        
        // notification message
        $messageToSend = isset($_POST['message_to_send']) ? $_POST['message_to_send'] : '';
        ChromePhp::log('Message Title '.$messageTitle." Message:".$messageToSend);

        $userslist_with_fcm_id = $db->getUsersFCMId($ucategory);
        ChromePhp::log('FCM LIST  '.$userslist_with_fcm_id->num_rows);
        // var_dump($userslist_with_fcm_id);


        $push->setTitle($messageTitle);
        $push->setMessage($messageToSend);

        $push->setIsBackground(FALSE);

        $json = '';
        $response = '';

        if ($userslist_with_fcm_id->num_rows > 0) {
             while ($row = mysqli_fetch_array($userslist_with_fcm_id)){
             
             ChromePhp::log('FCM ID  '.$row['fcm_id']);
             
             $json = $push->getPush();
             
             $regId = $row['fcm_id'];
             $response = $firebase->send($regId, $json);
                                            }
                                        }
                                  
       else{
              echo '<h3>Oops ! You got empty data</h3>';
           }
        var_dump($response);       
}
    
?>


<!DOCTYPE html>
<html>
 <head>
  <title>Admin Panel</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- jQuery UI -->
<link href="https://code.jquery.com/ui/1.10.3/themes/redmond/jquery-ui.css" rel="stylesheet" media="screen">

<!-- Bootstrap -->
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- styles -->
<link href="css/styles.css" rel="stylesheet">

<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link href="vendors/form-helpers/css/bootstrap-formhelpers.min.css" rel="stylesheet">
<link rel="stylesheet" href="css/pure-min.css">

<link href="css/forms.css" rel="stylesheet">


<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
  <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
    <style type="text/css">
        body{
        }
        div.container{
            width: 1000px;
            margin: 0 auto;
            position: relative;
        }
        legend{
            font-size: 30px;
            color: #555;
        }
        .btn_send{
            background: #00bcd4;
        }
        label{
            margin:10px 0px !important;
        }
        textarea{
            resize: none !important;
        }
        .fl_window{
            width: 400px;
            position: absolute;
            right: 0;
            top:100px;
        }
        pre, code {
            padding:10px 0px;
            box-sizing:border-box;
            -moz-box-sizing:border-box;
            webkit-box-sizing:border-box;
            display:block; 
            white-space: pre-wrap;  
            white-space: -moz-pre-wrap; 
            white-space: -pre-wrap; 
            white-space: -o-pre-wrap; 
            word-wrap: break-word; 
            width:100%; overflow-x:auto;
        }

    </style>

    <script type="text/javascript">



    function sendMessage()
    {
        // alert("method called");
        var chx = document.getElementsByTagName('input');

        for (var i=0; i<chx.length; i++) 
        {
                // If you have more than one radio group, also check the name attribute
                // for the one you want as in && chx[i].name == 'choose'
                // Return true from the function on first match of a checked item
                if (chx[i].type == 'radio' && chx[i].checked) 
                {
                    // alert("checked: "+chx[i].value);
                    $.ajax({
                            url: 'test.php',
                            type: 'post',
                            data: {
                                send:"true",
                                user_category :chx[i].value,
                                message_title : document.getElementById('title').value,
                                message_to_send : document.getElementById('message').value
                                  },
                            success: function(data, textStatus, jqXHR)
                                {
                                    //data - response from server
                                    // alert("success  :".textStatus);
                                },
                                error: function (jqXHR, textStatus, errorThrown)
                                {
                                    // alert("failed :".textStatus);
                                }   
                        });
                        
                }
    
        
    }
}
</script>

  </head>
  <body>
    <div class="header">
     <div class="container">
        <div class="row">
           <div class="col-md-5">
              <!-- Logo -->
              <div class="logo">
                 <h1><a href="index.php">Admin Panel</a></h1>
              </div>
           </div>
           <div class="col-md-5">
             
           </div>
           <div class="col-md-6">
              <div class="navbar navbar-inverse" role="banner">
                  <nav class="collapse navbar-collapse bs-navbar-collapse navbar-right" role="navigation">
                    <ul class="nav navbar-nav">
                      <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">My Account <b class="caret"></b></a>
                        <ul class="dropdown-menu animated fadeInUp">
                            <li><a href="updateProfile.php">Update Profile</a></li>
                          <li><a href="logout.php">Logout</a></li>
                        </ul>
                      </li>
                    </ul>
                  </nav>
              </div>
           </div>
        </div>
     </div>
</div>

<div class="page-content">
    <div class="row">
      <div class="col-md-2">
        <div class="sidebar content-box" style="display: block;">
            <ul class="nav">
                <!-- Main menu -->
                
                <li><a href="index.php"><i class="glyphicon glyphicon-tasks"></i>App Users</a></li>
                <li><a href="halt_sponsors_senate.php"><i class="glyphicon glyphicon-tasks"></i>Senate HALT Supporters</a></li>
                <li><a href="halt_sponsors_assembly.php"><i class="glyphicon glyphicon-tasks"></i>Assembly HALT Supporters</a></li>
                <li><a href="brief_call_history.php"><i class="glyphicon glyphicon-tasks"></i>Call History</a></li>                   
                <li><a href="send_message.php"><i class="glyphicon glyphicon-tasks"></i>Send Messages</a></li>                   
                <!-- <li><a href="voice_prompt_form.php"><i class=class="glyphicon glyphicon-tasks"></i>Voice Prompt</a></li> -->
             
                </li>
            </ul>
         </div>
      </div>
      <div class="col-md-10">
            <div class="row">
                
                <div class="col-md-12">
                    <div class="content-box-large">
                        <div class="panel-body">
                                
                 
                            <form class="pure-form pure-form-stacked" method="POST">
                                <fieldset>
                                    <legend>Create Message</legend>
    
                                    <label for="title">Title</label>
                                    <input type="text" value="Support Halt" id="title" name="title" class="pure-input-1-2" placeholder="Enter title">
                 
                                    <label for="message">Message</label>
                                    <textarea class="pure-input-1-2" name="message" id="message" placeholder="Notification message!" rows="5" >Hello World</textarea>
                                    
                                    <br>
                                       <h5> 
                                        <input type="radio" id="user_category" name="user_category" value="userswithopponents"> Users with opponents<br>
                                        <br>
                                        <input type="radio" id="user_category" name="user_category" value="userswithsupporters"> Users with supporters<br>
                                        <br>
                                        <input type="radio" id="user_category" name="user_category" value="everyone"> Everyone <br>                                            
                                        <br>
                                        <input type="radio" id="user_category" name="user_category" value="nyresidentsonly"> NY residents only </h5>

                                </br>
                 
                                   
                                    <input type="hidden" name="push_type" value="individual"/>
                                    <button type="submit" class="btn btn-primary" onclick="sendMessage()">Send</button>
                                </fieldset>
                            </form>
                        </div>

                    </div>
                </div>
            </div>
      </div>


    </div>
</div>



<link href="vendors/datatables/dataTables.bootstrap.css" rel="stylesheet" media="screen">

<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://code.jquery.com/jquery.js"></script>
<!-- jQuery UI -->
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="bootstrap/js/bootstrap.min.js"></script>

<script src="vendors/datatables/js/jquery.dataTables.min.js"></script>

<script src="vendors/datatables/dataTables.bootstrap.js"></script>

<script src="js/custom.js"></script>
<script src="js/tables.js"></script>

所以,到目前为止,我已经尝试从数据库和调用发送方法中迭代所有 reg_id,但它没有向任何设备发送通知。

【问题讨论】:

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


【解决方案1】:

尝试将多个设备的设备 ID 作为数组发送。在你的情况下,

$registration_ids 必须是设备 ID 数组。

例如

$registration_ids = array('Device ID 1', 'Device ID 2');

【讨论】:

  • 如果我有 100 万用户怎么办?最大限制是多少?
【解决方案2】:

如果您要通过终端发送通知,curl 命令的数据部分将如下所示:

{
"registration_ids": ["device_token_1", "device_token_2"],
"notification": {
    "body": "Hello",
    "title": "Hello",
    "vibrate": 1,
    "sound": 1
 }
}

PHP 代码:

$body = array(
        'registration_ids' => array("device_token_1", "device_token_2"),
        'notification' => array('body' => 'Hello', 'title' => 'Hello', 'vibrate' => 1, 'sound' => 1)
    );

【讨论】:

  • 所以我应该只在使用一个设备ID发送时使用to
  • @NimitBhargava 如果您有一台设备,registration_ids 数组将仅包含一个 device_token 字符串。无需使用to
【解决方案3】:

如果您想发送给多个用户,请使用“registrations_ids”代替“to”:

$fields = array
(
    'registration_ids'  => $tokens,
    'notification'   => $msg


);

其中 $tokens = array("设备令牌 1" , "设备令牌 2");

如果您想发送给单个用户,请使用 'to' ,例如

$fields = array
(
    'to'  => $token,
    'notification'   => $msg


);

其中 $token = "设备令牌 1";

【讨论】:

    【解决方案4】:
    $notification_data = $this->common->get_all_record('table name',array()); //get all id from table
    
                if($notification_data != NULL){
                    foreach ($notification_data as $notification_data_row) {
                        $registrationIds = $notification_data_row['token'];
                    #prep the bundle
                        $msg = array
                            (
                            'body'  => 'body msg',
                            'title' => 'title',
                            'icon'  => 'myicon',/*Default Icon*/
                            'sound' => 'mySound'/*Default sound*/
                            );
                        $fields = array
                            (
                            'to'            => $registrationIds,
                            'notification'  => $msg
                            );
                        $headers = array
                            (
                            'Authorization: key=' . "your key",
                            'Content-Type: application/json'
                            );
                    #Send Reponse To FireBase Server
                        $ch = curl_init();
                        curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
                        curl_setopt( $ch,CURLOPT_POST, true );
                        curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
                        curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
                        curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
                        curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
    
                        $result = curl_exec ( $ch );
                        // echo "<pre>";print_r($result);exit;
                        curl_close ( $ch );
                    }
                }
    

    【讨论】:

    • 为我工作.. 谢谢
    • 如果您的数组很大,您可能会在遍历数组时超过服务器上的最大执行时间。如果我错了,请纠正我。
    • 这不是最好/正确的方法。
    【解决方案5】:

    一次向多个用户发送 Firebase 通知

    将多个 firebase 令牌添加到数组中。

    $token_ids = array('token1', 'token2');
    

    将令牌传递给下面显示的函数

    使用下面显示的功能,您还可以发送带有通知的图像

    如果您不想发送任何图像,则只需传递空字符串

    sendFirebaseNotification($token_ids ,"notification title", "message", "image_url");
    

    我用这个功能

    function sendFirebaseNotification($fb_key_array, $title, $message, $imageURL){
        $authorization_key = "your_auth_key";
    
        $finalPostArray = array('registration_ids' => $fb_key_array,
                                'notification' => array('body' => $message,
                                                        'title' => $title,
                                                        "image"=> $imageURL),
                                "data"=> array("click_action"=> "FLUTTER_NOTIFICATION_CLICK",
                                                "sound"=> "default", 
                                                "status"=> "done")); 
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,"https://fcm.googleapis.com/fcm/send");
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS,json_encode($finalPostArray));  //Post Fields
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: key='.$authorization_key));
        $server_output = curl_exec ($ch);
        curl_close ($ch);
        //echo $server_output; 
    }
    

    【讨论】:

      【解决方案6】:

      以下是发送通知的简单脚本。试试这个。

      <?php 
      $tokens = array('token_1','token_2','token_3');
      $title = "Title Here";
      $msg = "Subtitle or description Here";
      //Custom Parameters if any
      $customParam = array(
         'redirection_id' => '2',
         'redirection_type' => 'post_page' //'post_page','category_page','blog_page'
      );
      push_notification_android($tokens,$title,$msg,$customParam);
      function push_notification_android($tokens,$title,$msg,$customParam) {
      $url = 'https://fcm.googleapis.com/fcm/send';
      $api_key = 'fcm_server_api_key';
      $messageArray = array();
      $messageArray["notification"] = array (
          'title' => $title,
          'message' => $msg,
          'customParam' => $customParam,
      );
      $fields = array(
          'registration_ids' => $tokens,
          'data' => $messageArray,
      );
      $headers = array(
          'Authorization: key=' . $api_key, //GOOGLE_API_KEY
          'Content-Type: application/json'
      );
      // Open connection
      $ch = curl_init();
      // Set the url, number of POST vars, POST data
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      // Disabling SSL Certificate support temporarly
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
      // Execute post
      $result = curl_exec($ch);
      if ($result === FALSE) {
          echo 'Android: Curl failed: ' . curl_error($ch);
      }
      // Close connection
      curl_close($ch);
      return $result;
      }
      ?>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-27
        • 2014-11-09
        • 2011-08-03
        相关资源
        最近更新 更多