sending push notifications to multiple android dev

2019-01-06 12:45发布

问题:

I am following http://javapapers.com/android/google-cloud-messaging-gcm-for-android-and-push-notifications/? to send push notifications via GCM. Everything works fine but, i am able to send push notification to just one device. Registering another device replaces registration id of previous device. I tried solution provided by Shardool in http://javapapers.com/android/android-multicast-notification-using-google-cloud-messaging-gcm/? but its not working.

Any suggestion would be of great help.

Here are my gcm.php codes that registers device and sends push notifications but, only to a single device registered recently.

gcm.php

<?php
//generic php function to send GCM push notification
function sendPushNotificationToGCM($registatoin_ids, $message) {
    //Google cloud messaging GCM-API url
    $url = 'https://android.googleapis.com/gcm/send';
    $fields = array(
        'registration_ids' => $registatoin_ids,
        'data' => $message,
    );
    // Google Cloud Messaging GCM API Key
    define("GOOGLE_API_KEY", "MY_KEY");       
    $headers = array(
        'Authorization: key=' . GOOGLE_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_POSTFIELDS, json_encode($fields));
    $result = curl_exec($ch);             
    if ($result === FALSE) {
        die('Curl failed: ' . curl_error($ch));
    }
    curl_close($ch);
    return $result;
}
?>
<?php
//this block is to post message to GCM on-click
$pushStatus = "";   
if ( ! empty($_GET["push"])) { 
    $gcmRegID  = file_get_contents("GCMRegId.txt");
    $pushMessage = $_POST["message"];   
    if (isset($gcmRegID) && isset($pushMessage)) {      
        $gcmRegIds = array($gcmRegID);
        $message = array("m" => $pushMessage);  
        $pushStatus = sendPushNotificationToGCM($gcmRegIds, $message);
    }       
}
//this block is to receive the GCM regId from external (mobile apps)
if ( ! empty($_GET["shareRegId"])) {
    $gcmRegID  = $_POST["regId"]; 
    file_put_contents("GCMRegId.txt",$gcmRegID);
    echo "Ok!";
    exit;
}   
?>
<html>
    <head>
        <title>Google Cloud Messaging (GCM) Server in PHP</title>
    </head>
    <body>
        <h1>Google Cloud Messaging (GCM) Server in PHP</h1> 
        <form method="post"   action="gcm.php/?push=1">                                              
            <div>                                
                <textarea rows="2" name="message" cols="23" placeholder="Message to transmit via   GCM"></textarea>
            </div>
            <div><input type="submit"  value="Send Push Notification via GCM" /></div>
        </form>
        <p><h3><?php echo $pushStatus; ?></h3></p>        
    </body>
</html>

Please tell me how do I store multiple device registration ids in GCMRegid.txt and send notifications to each of the registered device

回答1:

Here I rewrote the php using mysql rather than retrieving the keys from file. In this case, I retrieve all the regIds from the table and put them in an array and pass it to sendPushNotification function to push the message to all. here you have 2 files, one for connect to database and one for GCM:

connect.php:

<?php

    $db_host = "localhost";
    $db_user = "root"; //change to your database username, it is root by default
    $db_pass = '';     //change to your database password, for XAMPP it is nothing for WAMPP it is root
    $db_db = 'gcmFirst'; //change to your database name

    if(!@mysql_connect($db_host, $db_user, $db_pass) || !@mysql_select_db($db_db)) {
        die('couldnt connect to database ' .mysql_error());
    }

?>

gcm.php

<?php
require 'connect.php';

function sendPushNotification($registration_ids, $message) {

    $url = 'https://android.googleapis.com/gcm/send';
    $fields = array(
        'registration_ids' => $registration_ids,
        'data' => $message,
    );

    define('GOOGLE_API_KEY', 'AIzaSyCjctNK2valabAWL7rWUTcoRA-UAXI_3ro');

    $headers = array(
        'Authorization:key=' . GOOGLE_API_KEY,
        'Content-Type: application/json'
    );
    echo json_encode($fields);
    $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_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

    $result = curl_exec($ch);
    if($result === false)
        die('Curl failed ' . curl_error());

    curl_close($ch);
    return $result;

}

$pushStatus = '';

if(!empty($_GET['push'])) {

    $query = "SELECT regId FROM users";
    if($query_run = mysql_query($query)) {

        $gcmRegIds = array();
        while($query_row = mysql_fetch_assoc($query_run)) {

            array_push($gcmRegIds, $query_row['regId']);

        }

    }
    $pushMessage = $_POST['message'];
    if(isset($gcmRegIds) && isset($pushMessage)) {

        $message = array('message' => $pushMessage);
        $pushStatus = sendPushNotification($gcmRegIds, $message);

    }   
}

if(!empty($_GET['shareRegId'])) {

    $gcmRegId = $_POST['regId'];
    $query = "INSERT INTO users VALUES ('', '$gcmRegId')";
    if($query_run = mysql_query($query)) {
        echo 'OK';
        exit;
    }   
}
?>

<html>
    <head>
        <title>Google Cloud Messaging (GCM) Server in PHP</title>
    </head>
    <body>
    <h1>Google Cloud Messaging (GCM) Server in PHP</h1>
    <form method = 'POST' action = 'gcm.php/?push=1'>
        <div>
            <textarea rows = 2 name = "message" cols = 23 placeholder = 'Messages to Transmit via GCM'></textarea>
        </div>
        <div>
            <input type = 'submit' value = 'Send Push Notification via GCM'>
        </div>
        <p><h3><?php echo $pushStatus ?></h3></p>
    </form>
    </body>
</html>

all you have to do is create a database that has a users table with id, regId and name as columns.

Hope this is what you are looking for



回答2:

I have modified the above gcm.php a little to meet my needs:

  1. The page should be automatically reloaded to it's original form after sending push notification.
  2. It should show the number of users registered.
  3. GCM doesn't allow more than 1000 regId at a time. So it should tackle that situation. (sending packets of 1000 pushnotifications in a loop).

gcm_main.php:

<?php
require 'connect.php'; //this is the same as as other answers on this topic

function sendPushNotification($registration_ids, $message) {

    $url = 'https://android.googleapis.com/gcm/send';
    $fields = array(
        'registration_ids' => $registration_ids,
        'data' => $message,
    );

    define('GOOGLE_API_KEY', 'your_google_api_key_here');

    $headers = array(
        'Authorization:key=' . GOOGLE_API_KEY,
        'Content-Type: application/json'
    );
    echo json_encode($fields);
    $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_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

    $result = curl_exec($ch);
    if($result === false)
        die('Curl failed ' . curl_error());

    curl_close($ch);
    return $result;

}

function redirect($url)
{
    if (!headers_sent())
    {    
        header('Location: '.$url);
        exit;
        }
    else
        {  
        echo '<script type="text/javascript">';
        echo 'window.location.href="'.$url.'";';
        echo '</script>';
        echo '<noscript>';
        echo '<meta http-equiv="refresh" content="0;url='.$url.'" />';
        echo '</noscript>'; exit;
    }
}


$pushStatus = '';

if(!empty($_GET['push'])) {

    $query = "SELECT gcm_regid FROM gcm_users";
    if($query_run = mysql_query($query)) {

        $gcmRegIds = array();
        while($query_row = mysql_fetch_assoc($query_run)) {

            array_push($gcmRegIds, $query_row['gcm_regid']);

        }

    }
    $pushMessage = $_POST['message'];
    if(isset($gcmRegIds) && isset($pushMessage)) {

        $message = array('price' => $pushMessage);
    $regIdChunk=array_chunk($gcmRegIds,1000);
    foreach($regIdChunk as $RegId){
    $pushStatus = sendPushNotification($RegId, $message);}

    }   
   $url="url_to_this_php_file";
         redirect($url);

}


if(!empty($_GET['shareRegId'])) {

    $gcmRegId = $_POST['gcm_regid'];
    $query = "INSERT INTO gcm_users VALUES ('', '$gcmRegId')";
    if($query_run = mysql_query($query)) {
       // echo 'OK';
        exit;
    }   
}
?>

<html>
    <head>
        <title>Whatever Title</title>
    </head>
    <body>

        <?php
        include_once 'db_functions.php';
        $db = new DB_Functions();
        $users = $db->getAllUsers();
        if ($users != false)
            $no_of_users = mysql_num_rows($users);
        else
            $no_of_users = 0;
        ?>
    <h1>Whatever you want</h1>
    <h2>Whatever you want</h2>
    <h3>Push Notification Admin Panel</h3>
    <h4>Current Registered users: <?php echo $no_of_users; ?></h4>
    <h4></h4>
    <form method = 'POST' action = 'gcm_main.php/?push=1'>
        <div>
            <textarea rows = "3" name = "message" cols = "75" placeholder = "Type message here"></textarea>
        </div>
        <div>
            <input type = "submit" value = "Send Notification">
        </div>

    </form>
    </body>
</html>

db_connect.php:

    <?php

    class DB_Connect {

        // constructor
        function __construct() {

        }

        // destructor
        function __destruct() {
            // $this->close();
        }

        // Connecting to database
        public function connect() {
            require_once 'config.php';
            // connecting to mysql
            $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
            // selecting database
            mysql_select_db(DB_DATABASE);

            // return database handler
            return $con;
        }

        // Closing database connection
        public function close() {
            mysql_close();
        }

    } 
    ?>

db_functions.php:

        <?php

    class DB_Functions {

        private $db;

        //put your code here
        // constructor
        function __construct() {
            include_once './db_connect.php';
            // connecting to database
            $this->db = new DB_Connect();
            $this->db->connect();
        }

        // destructor
        function __destruct() {

        }

        /**
         * Storing new user
         * returns user details
         */
        public function storeUser($name, $email, $gcm_regid) {
            // insert user into database
            $result = mysql_query("INSERT INTO gcm_users(name, email, gcm_regid, created_at) VALUES('$name', '$email', '$gcm_regid', NOW())");
            // check for successful store
            if ($result) {
                // get user details
                $id = mysql_insert_id(); // last inserted id
                $result = mysql_query("SELECT * FROM gcm_users WHERE id = $id") or die(mysql_error());
                // return user details
                if (mysql_num_rows($result) > 0) {
                    return mysql_fetch_array($result);
                } else {
                    return false;
                }
            } else {
                return false;
            }
        }

        /**
         * Get user by email and password
         */
        public function getUserByEmail($email) {
            $result = mysql_query("SELECT * FROM gcm_users WHERE email = '$email' LIMIT 1");
            return $result;
        }

        /**
         * Getting all users
         */
        public function getAllUsers() {
            $result = mysql_query("select * FROM gcm_users");
            return $result;
        }

        /**
         * Check user is existed or not
         */
        public function isUserExisted($id) {
            $result = mysql_query("SELECT gcm_regid from gcm_users WHERE gcm_regid = '$id'");
            $no_of_rows = mysql_num_rows($result);
            if ($no_of_rows > 0) {
                // user existed
                return true;
            } else {
                // user not existed
                return false;
            }
        }

    public function deleteUser($id){
    $result=mysql_query("DELETE FROM gcm_users WHERE gcm_regid = '$id'");

    }    


    }

?>

config.php:

<?php
/**
 * Database config variables
 */
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWORD", "");
define("DB_DATABASE", "gcm");

/*
 * Google API Key
 */
define("GOOGLE_API_KEY", "your_google_api_key_here"); // Place your Google API Key
?>

EDIT:

I have re-written the PHP code with some refinements and using MySqli (instead of MySql). It's in Github.



回答3:

Sending Push Notification to multiple devices is same as we send to individual device. Just store the registration token of all registered device to your server. And when calling the push notification with curl (I am assuming you are using php as server side) Put all the registration id in an array. This is a sample code

<?php
//Define your GCM server key here 
define('API_ACCESS_KEY', 'your server api key');

//Function to send push notification to all 
function sendToAll($message)
{
    $db = new DbOperation();
    $tokens = $db->getAllToken();
    $regTokens = array();
    while($row = $tokens->fetch_assoc()){
        array_push($regTokens,$row['token']);
    }
    sendNotification($regTokens,$message);
}


//function to send push notification to an individual 
function sendToOne($email,$message){
    $db = new DbOperation();
    $token = $db->getIndividualToken($email);
    sendNotification(array($token),$message);
}


//This function will actually send the notification
function sendNotification($registrationIds, $message)
{
    $msg = array
    (
        'message' => $message,
        'title' => 'Android Push Notification using Google Cloud Messaging',
        'subtitle' => 'www.simplifiedcoding.net',
        'tickerText' => 'Ticker text here...Ticker text here...Ticker text here',
        'vibrate' => 1,
        'sound' => 1,
        'largeIcon' => 'large_icon',
        'smallIcon' => 'small_icon'
    );

    $fields = array
    (
        'registration_ids' => $registrationIds,
        'data' => $msg
    );

    $headers = array
    (
        'Authorization: key=' . API_ACCESS_KEY,
        'Content-Type: application/json'
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://android.googleapis.com/gcm/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);
    curl_close($ch);

    $res = json_decode($result);

    $flag = $res->success;
    if($flag >= 1){
        header('Location: index.php?success');
    }else{
        header('Location: index.php?failure');
    }
}

Source: Google Cloud Messaging Tutorial



回答4:

Following code work for me to send notification to all registered users:

<?php
header("Access-Control-Allow-Origin: *"); 

$db_host = 'localhost'; //hostname
$db_user = ''; // username
$db_password = ''; // password
$db_name = ''; //database name
$link = mysqli_connect($db_host,$db_user,$db_password, $db_name);




$query = "select * from device_notification_id";
$result = mysqli_query ($link,$query);
while($row=mysqli_fetch_array($result)){
 		
 		$device_to[] =  $row[device_id];
 		
 			
}



if(isset($_POST['submit'])){

$title=$_POST['title'];
$message=$_POST['message'];
for($i=0 ; $i< sizeof($device_to) ; $i++)
{
//echo $to[$i];

$to = $device_to[$i];

sendPush($to,$title,$message);
}


}
	function sendPush($to,$title,$message)
	{
// API access key from Google API's Console
// replace API
		define( 'API_ACCESS_KEY', 'AIdfSyCd8ha2wop84LKtpQvRmCEiY8ZLpeTg2-o');
		$registrationIds = array($to);
		
		

	$msg = array
	(
	'message' => $message,
	'title' => $title,
	'vibrate' => 1,
	'sound' => 1

// you can also add images, additionalData
);


	$fields = array
	(
		'registration_ids' => $registrationIds,
		'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);

$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/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 );
curl_close( $ch );

echo $result;
}


?>
<html>
<form  method="POST">
<input type="text" name="title">
<input type="text" name="message">
<input type="submit" name="submit" value="submit">
</form>
</html>