Sending Push Notification messages to more than 1000 users at once

1

This question is very common and I have seen some posts in the English Stack that exemplify (without being very objective) how to solve the problem. GCM limits the sending of the same message to 1000 devices registered in a database, all at once. If there are more than 1000 devices the message is not even sent. It would take a Loop that would separate the records into batches of 1000 records and make a leap every amount. If you have 5000 would be 5 reps of 1000 for the same message: Below is the PHP code that I got (and is the same on several sites) and that limits me to this amount, would anyone have any 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);
}
    
asked by anonymous 05.07.2016 / 14:50

2 answers

2

You can use array_chunk to split into 1000 pieces and then submit.

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);
    }

}
    
05.07.2016 / 15:26
1

I found another solution that does the same thing as previously submitted code, 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);
    
15.07.2016 / 20:56