Sending Push Notification messages to more than 1000 users at once

Asked

Viewed 220 times

1

This doubt is very frequent and I’ve seen some Stack posts in English that exemplify (without being too objective) how to solve the problem. The GCM limits the sending of the same message to 1000 devices registered in a database, at once. If there are more than 1000 devices the message is not even sent. It would take a Loop that separates the records in batches of 1000 records and jumps each amount. Ex. if you have 5000 would be 5 repetitions of 1000 for the same message: Below is the PHP code I got (and it’s the same on several websites) and that limits me to this amount, someone would have some solution?

class GCM {

    function __construct(){}

    public function send_notification ($registatoin_ids, $data) {

        require "includes/google_api_key.php";

        // GOOGLE API KEY
        define ("GOOGLE_API_KEY", $google_api_key);

        $url = "https://android.googleapis.com/gcm/send";

        $fields = array (
            "registration_ids" => $registatoin_ids,
            "data" => $data,
        );
        //var_dump($fields);
        $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_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
        $result_gcm=curl_exec($ch);
        if($result_gcm===FALSE) {
            die("Curl failed: ".curl_error($ch));
        }
        curl_close($ch);
        //echo $result_gcm;
    }
}



// Create connection
$conn = mysqli_connect($mysqlHost, $mysqlUser, $mysqlPwd, $mysqlDbname);

// Check connection
if (!$conn) {
    die ("Connection failed: " . mysqli_connect_error());
}


$result = $conn->query("SELECT * FROM tbl_notification WHERE users_android_token IS NOT NULL AND users_android_token <> ''");

$android_tokens = array();
$x = 0;

if ($result -> num_rows > 0) {       // Acredito que aqui seria  
                                     // o local para inserir um laço for
    // output data of each row
    while($row = $result -> fetch_assoc()) {
         $android_tokens[] = $row["users_android_token"];
    $x++;
    }
} else {
    echo "";
}
$conn -> close();

$title  = $_POST['title'];
$msg    = $_POST['message'];
$link   = $_POST['link'];

if ($android_tokens != array()) {
    $gcm  = new GCM();
    $data = array("title" => $title,"description" => $msg,"link" => $link);
    $result_android = $gcm -> send_notification($android_tokens,$data);
}

2 answers

2


You can use the array_chunk to split into pieces of 1000 and then send.

if ($android_tokens != array()) {
    $gcm  = new GCM();
    $data = array("title" => $title,"description" => $msg,"link" => $link);

    //Dividi o array contendo 1000 tokens
    $splitTokens = array_chunk($android_tokens, 1000);

    //Da um looping no array dividido e envia em lotes de 1000
    //Obs: o último lote pode conter menos
    foreach($splitTokens as $tokens) {
        $result_android = $gcm -> send_notification($tokens,$data);
    }

}
  • Excellent. I had already seen this suggestion in Stack in English, but not so objectively. Insert this into my script and now I must let it reach 1,000 users again. I had deleted some records to continue sending. Once I get a positive return I mark as sure.

  • Jeferson Assis, perfect your solution. Today the BD is over 1.005 and the system continues working.

1

I found another solution that does the same thing as the code sent earlier, just so that anyone who has problems with one way, can try the other:

Insert after :

$result = $conn->query("SELECT * FROM users WHERE user_android_token IS NOT NULL AND user_android_token <> '' ORDER BY user_id");


SUBSTITUIR POR ESTE

$android_tokens = array();
$x=0;
$i=0;
if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {

  $android_tokens[$i][] = $row["user_android_token"];
  $x++;
  // I need divide the array for 1000 push limit send in one time
  if ($x % 800 == 0) {
    $i++;
  }     
    }
} else {
    echo "0 results";
}
$ip= $_SERVER['REMOTE_ADDR'];
$result_check = $conn->query("SELECT * FROM `notifications` WHERE notification_sender_ip = '$ip' && notification_date > DATE_SUB(NOW(),INTERVAL 5 MINUTE)");
if ($result_check->num_rows > 2) {
        die('Anti flood protection. You can send only 3 notifications every 5 minutes!. This is just a demo push panel, buy this from codecanyon and install into your hosting. Thanks!');
}

$title = $_POST['title'];
$msg = $_POST['message'];
$link = $_POST['link'];

if ($android_tokens != array()) {
    $gcm=new GCM();
    $data=array("title"=>$title,"description"=>$msg,"link"=>$link);
    foreach ($android_tokens as $tokens) {
      $result_android = $gcm->send_notification($tokens,$data);
      sleep(1);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.