简体   繁体   中英

Multiple Notifications Getting Delivered From GCM

I am using PHP to send Notifications on multiple android devices at a time. All registration ids are unique, following is the CURL request that I am sending.

$url='https://android.googleapis.com/gcm/send';
$headers = array(
                'Authorization: key=' . ANDROID_KEY,
                'Content-Type: application/json'
            );
$registration_ids = [];//with multiple registration ids
$notification = array(
                'registration_ids' => $registration_ids,
                'data'             => array('notification_id' => $data['notification_id'],
                                            'title'           => $data['title'],
                                            'message'         => $data['message'])
            );
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($notification));           
$res = curl_exec($ch);

After debugging multiple times I could not find any reason for multiple notifications(more than 10 times) on the same device.

Is there any way to check the log of requests received by GCM. Any lead will be appreciated.

I figured the problem was with my android implementation. The device was getting registered multiple times.

GCM returns the same registration id for a device till the next reinstall. In some cases when the registration id gets expired/invalid GCM returns a new one.

At the time of pushing GCM will return the canonical registration id for expired/invalid token.

The solution is to read the response and update old registration id with the new one in the db.

add at the end of code

echo json_encode($res);

and see the result from CGM. Maybe you can see the result there, if it is still a problem, paste it here.

Try below code. I already used this and works perfectly:

$registrationIDs[] = array();//All device tokens

// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
    'registration_ids' => $registrationIDs,
        'data' => $param,
);
$headers = array(
    'Authorization: key=' . $apiKey, // ANDROID PUSH NOTIFICATION 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);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

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

// Close connection
curl_close($ch);

If you still receive multiple Notifications. You have to manage device Tokens.

Each device may have multiple device tokens. So You have to manage this with Device Id. Follow This step:

  1. While registering a device token You have to check it with Device ID (Combination of Device ID and Device Token in One Table). So before saving check for Device ID and update Token accordingly so that we can have latest device token for that device. Each device has unique Device ID.

  2. While User signs in register device token and device id. When a user logs out just make device token empty. So that for next time we can update device token based on device id

GCM had some problems in it. That is why google launched Firebase Cloud Messaging (FCM). Check out the documentation from here .

Below is a sample code which I used in my projects. Test it with your Android device id and FCM server key.

$data = array(
    'to' => 'XXXXXXXXXXXdevice_idXXXXX',
    "priority" => "high",
    'data' => [
        'title' => 'Test Title',
        'body' => 'Test Body',
    ]
);

$headers = array(
    "Content-Type:application/json"
);

$headers[] = "Authorization:key=XXXXXXSERVER KEYXXXXXXXXXX";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://fcm.googleapis.com/fcm/send");
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_TIMEOUT, 5 );
curl_setopt($ch, CURLOPT_HEADER, false);
//curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
$result = curl_exec($ch);

curl_close($ch);

If you print $result variable you will get a response like this. It will tell you whether your notification sent or not.

{"multicast_id":6375780930000000095,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:139000000000000cd617fcf9fd7ecd"}]} 

Refer these code

<?php

include "connection.php";

$msg = "New jobs for you";
$noti ="Jobsglance";

$sql = "SELECT gcmid FROM gcm";
// Executing the query
$result = mysql_query($sql);
  while($row = mysql_fetch_assoc($result))
  {
$regid[] = $row[gcmid];
}

define( 'API_ACCESS_KEY', 'AI******************' );

$registrationIds = $regid;
// Message Array
$msg = array
(

// <!--Message that we want to send in the push notification-->
'message' => $msg,


// <!--Title that we want to set for the push notification-->
'title' => $noti,

'subtitle' => 'This is a subtitle. subtitle',
'tickerText' => 'Ticker text here...Ticker text here...Ticker text here',

// Sets to true or '1' if we want device to vibrate and make sound when user recieves push notification
'vibrate' => 'default',
'sound' => 'default',
'largeIcon' => 'large_icon',
'smallIcon' => 'small_icon'
);

// RegistrationIds and message are assigned to fields
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$headers = array
(

// Setting headers for API acceess key and content type
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);

// <!--Initializing Curl-->
$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 );
echo $result;
 ?>

I was also facing same issue. There may be one of the solution from below:

  1. If only some devices are affected then remove app from those devices, restart those devices and then install app again.
  2. If multiple notification issue occur on all devices then check the device token of from app ie how many tokens are generated for one device via app.
  3. Check the response of curl. If GCM response is success for each device token then check if function is not getting called more than one time for same data. If response shows unreachable or likewise error, then there may a chance that curl retrying it continuously but not getting any response. Try online notification tester like https://pushtry.com/

On Application side in notification receive file.

from php side add unique id into notification payload. When you create notification. then set notification id to php Unique ID. And Set Pending Intent to FLAG_UPDATE_CURRENT.

This way if you receive multiple notification. It will append over it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM