Send multiple messages with GCM - php

I've been dealing with this issue since 2 days. What I want to do is, I've to send multiple messages to registered GCM device. Till now I can send single message to device. Below is the code to send message.
send_message.php
<?php
if (isset($_REQUEST["regId"]) && isset($_REQUEST["message"])) {
$regId = $_REQUEST["regId"];
$message = $_REQUEST["message"];
include_once './GCM.php';
$gcm = new GCM();
$registatoin_ids = array($regId);
$message = array("price" => $message);
$result = $gcm->send_notification($registatoin_ids, $message);
echo $registatoin_ids; echo $message;
echo $result;
}
GCM.php
<?php
class GCM {
//put your code here
// constructor
function __construct() {
}
//Sending Push Notification
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'message' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
//print_r($headers); exit();
// 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) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
}
?>
Here message is being received on receiver side..
// code for this is in GCM.php
$fields = array(
'registration_ids' => $registatoin_ids,
'message' => $message,
);
But I want to send multiple messages in single notification. for that what I did...
send_message.php
<?php
if (isset($_REQUEST["regId"]) && isset($_REQUEST["message"]) && isset($_REQUEST["data"])) {
$regId = $_REQUEST["regId"];
$message = $_REQUEST["message"];
$data = $_REQUEST["data"]; //added third parameter
include_once './GCM.php';
$gcm = new GCM();
$registatoin_ids = array($regId);
$message = array("price" => $message);
$data = array("extra" => $data);
$result = $gcm->send_notification($registatoin_ids, $message, $data);
echo $registatoin_ids; echo $message; echo $data;
echo $result;
}
GCM.php
<?php
class GCM {
//put your code here
// constructor
function __construct() {
}
/**
* Sending Push Notification
*/
public function send_notification($registatoin_ids, $message, $data) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'message' => $message,
'data' => $data,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
//print_r($headers); exit();
// 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) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
}
?>
And in android I wrote the function to receive message like this...
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getStringExtra("price");
String newmessage = intent.getStringExtra("extra");
displayMessage(context, message + newmessage);
generateNotification(context, message + newmessage);
}
But I'm getting null result for "price" and getting result for "extra".
How can I receive multiple message string in single notification?

In send_message.php
Put both messages in the same object. I don't know why you call it price, but try like this:
$message = array('message' => $message,
'extra' => $data
);
In GCM.php
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
In your Android Service
protected void onMessage(Context context, Intent intent) {
//log the message in JSON format
Log.i(TAG, "Received message >> " + intent.getExtras().toString());
//Retrieve message and extra
String message = intent.getExtras().getString("message");
String newmessage = intent.getExtras().getString("extra");
//Now display the message
displayMessage(context, message + newmessage);
generateNotification(context, message + newmessage);
}

All the payload parameters you pass in your JSON should be within the data element.
Your JSON should look like this :
{
"registration_ids":["xxx", "yyy"],
"data": {
"price": "price value",
"extra": "extra value"
}
}
And not like this :
{
"registration_ids":["xxx", "yyy"],
"message": {
"price": "price value"
},
"data": {
"extra": "extra value"
}
}

you can write a JSON response that contain a multiple messages
and the you get the JSON in android , parse it and get your multiple Messages .

send_message.php
<?php
if (isset($_REQUEST["regId"]) && isset($_REQUEST["message"]) && isset($_REQUEST["extra"])) {
$regId = $_REQUEST["regId"];
$message = $_REQUEST["message"];
$extra= $_REQUEST["extra"];
include_once './GCM.php';
$gcm = new GCM();
$registatoin_ids = array($regId);
$message = array("message" => $message, "extra" => $extra);
$result = $gcm->send_notification($registatoin_ids, $message);
}
GCM.php
<?php
class GCM {
function __construct() {
}
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
//print_r($headers); exit();
// 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) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo 'result';
echo json_encode($fields);
echo $result;
}
}
Android side
/**
* Method called on Receiving a new message
* */
#Override
protected void onMessage(Context context, Intent intent) {
Log.i(TAG, "Received message");
String message = intent.getExtras().getString("extra");
String newmessage = intent.getExtras().getString("message");
displayMessage(context, message + newmessage);
generateNotification(context, message + newmessage);
}

Related

Flutter Firebase Messaging with PHP

I have successfully sent push notification from Firebase console using FCM registration token. This is my dart file:
class PushNotificationsManager {
PushNotificationsManager._();
factory PushNotificationsManager() => _instance;
static final PushNotificationsManager _instance = PushNotificationsManager._();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
bool _initialized = false;
Future<void> init() async {
if (!_initialized) {
// For iOS request permission first.
_firebaseMessaging.requestNotificationPermissions();
_firebaseMessaging.configure();
// For testing purposes print the Firebase Messaging token
String token = await _firebaseMessaging.getToken();
print("FirebaseMessaging token: $token");
_initialized = true;
}
}
}
Now I would like to send the push notification using PHP. I found this tutorial. The PHP code is as below:
push.php
<?php
/**
* #author Ravi Tamada
* #link URL Tutorial link
*/
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']['image'] = $this->image;
$res['data']['payload'] = $this->data;
$res['data']['timestamp'] = date('Y-m-d G:i:s');
return $res;
}
}
firebase.php
<?php
/**
* #author Ravi Tamada
* #link URL Tutorial link
*/
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 message to a topic by topic name
public function sendToTopic($to, $message) {
$fields = array(
'to' => '/topics/' . $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(
'to' => $registration_ids,
'data' => $message,
);
return $this->sendPushNotification($fields);
}
// function makes curl request to firebase servers
private function sendPushNotification($fields) {
require_once __DIR__ . '/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);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
return $result;
}
}
?>
The web console show returned success message, but my device didn't get the notification. What went wrong?
Problem solved by using this PHP code
<?php
$url = "https://fcm.googleapis.com/fcm/send";
$token = "firebase token";
$serverKey = 'Server key';
$title = "Title";
$body = "Body";
$notification = array('title' =>$title , 'body' => $body, 'sound' => 'default', 'badge' => '1');
$arrayToSend = array('to' => $token, 'notification' => $notification,'priority'=>'high');
$json = json_encode($arrayToSend);
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: key='. $serverKey;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST,"POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
//Send the request
$response = curl_exec($ch);
//Close request
if ($response === FALSE) {
die('FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
?>
try to configure your code as
protected function sendPushNotification($fields = array())
{
define( 'API_ACCESS_KEY', 'AAAA4-.....' );
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$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 );
curl_close( $ch );
return $result;
}
and use it like:
$msg = array
(
'body' => 'your message',
'title' => "your app name",
'vibrate' => 1,
'sound' => 1,
);
$fields = array
(
'to' => '/topics/your topic name', // or 'to'=> 'phone token'
'notification'=> $msg
);
$this->sendPushNotification($fields);
If this helps,
You need to add the handlers for the notification under _firebaseMessaging.configure();
Have you done this anywhere -
_firebaseMessaging.configure
(
onMessage: (Map<String, dynamic> message) async
{
print("onMessage: $message");
},
onLaunch: (Map<String, dynamic> message) async // Called when app is terminated
{
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async
{
print("onResume: $message");
}
);

Fixing GCM 1000 message limit, help loop script

I am using PHP to send GCM notification to users. Based on their token saved in SQL on server. But I have a limit of 1000 notifications at once to send,
this is my working code , now i need to edit it to loop the process, and send 5000 notification in sections, 1000 than 1000 etc.
Here is my PHP code, and a simple HTML I didn't post here,
<?php
$mysqlHost = "";
$mysqlUser = "";
$mysqlPwd = ";
$mysqlDbname = "";
class GCM {
function __construct(){}
public function send_notification($registatoin_ids,$data) {
// GOOGLE API KEY
define("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 users WHERE users_android_token IS NOT NULL AND users_android_token <> ''");
$android_tokens = array();
$x=0;
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$android_tokens[] = $row["users_android_token"];
$x++;
}
} else {
echo "0 results";
}
$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);
}
?>
Rather than send notification by registrationId, why not using send notification by topic. You only need to make client subscribed to certain topic.
in GCM, you can send notification topic with this code :
function send_notification_topic($topicname, $message){
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'to' => '/topics/' . $topicname,
'data' => $message
);
$headers = array(
'Authorization: key=AIzablablablayourServerKey',
'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));
$result = curl_exec($ch);
if($result === FALSE){
die('Curl failed : ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
Use this code for divided your tokens .
if ($android_tokens != array()) {
$gcm = new GCM();
$data = array("title" => $title,"description" => $msg,"link" => $link);
//Divide array into 1000 tokens
$splitTokens = array_chunk($android_tokens, 1000);
//loop the array
//Obs: for looping notification may push slow
foreach($splitTokens as $tokens) {
$result_android = $gcm -> send_notification($tokens,$data);
}
}
For divide GCM may push the notification slow . it take up to 2 - 10 mins.

GCM return null message

I am trying to get the message from server as a push notification in android. but I got null message from server when I change language to Thai but English working.
PHP File
class GCMPushMessage {
var $url = 'https://android.googleapis.com/gcm/send';
var $serverApiKey = "";
var $devices = array();
/*
Constructor
#param $apiKeyIn the server API key
*/
function GCMPushMessage($apiKeyIn){
$this->serverApiKey = $apiKeyIn;
}
/*
Set the devices to send to
#param $deviceIds array of device tokens to send to
*/
function setDevices($deviceIds){
if(is_array($deviceIds)){
$this->devices = $deviceIds;
} else {
$this->devices = array($deviceIds);
}
}
/*
Send the message to the device
#param $message The message to send
#param $data Array of data to accompany the message
*/
function send($message, $data = false){
if(!is_array($this->devices) || count($this->devices) == 0){
$this->error("No devices set");
}
if(strlen($this->serverApiKey) < 8){
$this->error("Server API Key not set");
}
$fields = array(
'registration_ids' => $this->devices,
'data' => array( "message" => $message ),
);
if(is_array($data)){
foreach ($data as $key => $value) {
$fields['data'][$key] = $value;
}
}
$headers = array(
'Authorization: key=' . $this->serverApiKey,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();
// Set the url, number of POST vars, POST data
curl_setopt( $ch, CURLOPT_URL, $this->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 ) );
// Avoids problem with https certificate
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false);
// Execute post
$result = curl_exec($ch);
// Close connection
curl_close($ch);
echo $result;
return $result;
}
function error($msg){
echo "Android send notification failed with error:";
echo "\t" . $msg;
exit(1);
}
onMessageReceived
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
String title = data.getString("title");
/*Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);*/
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
help me please.

GCM push notification return error: field data must be a json array

When I am using GCM for push notification , I got an error return as: field "data" must be a JSON array.
When user create the new post then notification will be send to all Registered devices. Any one have some idea of how to solve it? Thank you.
function Notification($post) {
global $wpdb;
$pub_post = get_post($post_ID);
$post_title=$pub_post->post_title;
$totalrecord = $this->get_allrecord();
$message = "Your New post, " .$post_title." has been published";
if (count($totalrecord) > 0) {
//$display_row = null;
foreach ($totalrecord as $row) {
$a = $row->token;
$this->sendPushNotification($a, $message);
}
}
}
function get_allrecord(){
global $wpdb;
$results =$wpdb->get_results('SELECT token FROM wp_push_tokens ', OBJECT);
return $results;
}
function sendPushNotification($registration_ids, $message) {
$apiKey = "xxxxxxxxxxxxxxxxxxxxxxx";
$headers = array("Content-Type:" . "application/json", "Authorization:" . "key=" . $apiKey);
$fields = array(
'register' =>$registration_ids,
'data' =>$message );
$ch = curl_init();
// Set the url, number of POST vars, POST data
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 );
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, wp_json_encode($fields));
// Execute post
$result = curl_exec($ch);
if($result === false)
die('Curl failed ' . curl_error());
// Close connection
curl_close($ch);
return $result;
}
Your content type is "application/json", which means the "data" field must be a JSON of the form :
"data": {
"message": "your message"
}
Note that the "message" key in this example is custom. You can use whatever keys you wish, and your app will have to search for those keys when it receives the message.
I don't know PHP, but something like this may work :
$fields = array(
'registration_ids' =>$registration_ids,
'data' => array('message' => $message));

Getting curly braces in output - GCM send multiple data

I am trying to send data to device with GCM but getting curly braces in output(as below image). I'm new to php and I wonder how to fix this issue. Here is the part of PHP server code :
public function send_notification($registatoin_ids, $message, $title) {
// include config
include_once './config.php';
$url = 'https://android.googleapis.com/gcm/send';
$data = array("title" => $title, "message" => $message);
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $data
);
$headers = array(
'Authorization: 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) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
echo $result;
}
/////////
I changed the send_message.php like this and it fixed.
if (isset($_GET["regId"]) && isset($_GET["message"]) && isset($_GET["title"])) {
$regId = $_GET["regId"];
$messagem = $_GET["message"];
$titlem = $_GET["title"];
include_once './GCM.php';
$gcm = new GCM();
$registatoin_ids = array($regId);
$message = array("message" => $messagem);
$title = array($titlem);
$result = $gcm->send_notification($registatoin_ids, $messagem, $titlem);
echo $result;`
}
EDIT: sorry, with JSON GCM payload data should be an assoc array. Mixed up with an older flavor of the protocol. That said, what is your intent on the Android side like?
EDIT: dump the whole extra bundle.
Bundle b = intent.getExtras();
for(String k : b.keySet())
Log.d("tag", k + "=" + b.get(k).toString());
edited:
ok, I think your problem is you're posting the value {.....} with no key. it's like saying
http://..... com?{myjson:"stuff"}
I haven't reviewed the api, but it seems it should be something like post "data=".json_encode($fields);

Categories