GCM发送多个通知的解决方法

28

我正在使用PHP一次性向多个Android设备发送通知。所有注册ID都是唯一的,以下是我发送的CURL请求。

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

调试多次后,我无法找到同一设备收到多个通知(超过10次)的原因。

是否有办法检查GCM接收到的请求日志?任何线索都将不胜感激。


发送该请求后的响应是什么? - Arthur Thompson
你尝试过使用通知负载而不是数据负载吗?请查看https://firebase.google.com/docs/cloud-messaging/concept-options - M Rostami
7个回答

1
我发现问题出在我的Android实现上。该设备被注册了多次。
GCM会为设备返回相同的注册ID,直到下一次重新安装。在某些情况下,当注册ID过期/无效时,GCM会返回一个新的ID。
在推送时,GCM将为过期/无效令牌返回规范的注册ID。
解决方案是读取响应并在数据库中使用新的注册ID更新旧的注册ID。

0

在代码末尾添加

echo json_encode($res);

然后从 CGM 查看结果。如果仍然有问题,可以将结果粘贴在这里。


0

在应用程序端接收通知文件。

从PHP端将唯一标识符添加到通知载荷中。 创建通知时,请将通知ID设置为PHP唯一ID。 并将Pending Intent设置为FLAG_UPDATE_CURRENT。

这样,如果您收到多个通知,它们会追加在其上。


0

我也遇到了同样的问题。 以下可能有一种解决方案:

  1. 如果只有一些设备受到影响,则从这些设备中删除应用程序,重新启动这些设备,然后再安装应用程序。
  2. 如果所有设备都出现多个通知问题,请检查应用程序生成的设备令牌数量。
  3. 检查curl的响应。如果每个设备令牌的GCM响应都成功,则检查是否对相同数据调用了多次函数。如果响应显示不可达或类似错误,则可能存在curl不断重试但未收到任何响应的情况。尝试使用在线通知测试工具,如https://pushtry.com/

0

GCM存在一些问题。这就是为什么谷歌推出了Firebase Cloud Messaging(FCM)。请从此处查看文档。

以下是我在项目中使用的示例代码。请使用您的Android设备ID和FCM服务器密钥进行测试。

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

如果您打印$result变量,您将得到这样的响应。它会告诉您通知是否已发送。
{"multicast_id":6375780930000000095,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:139000000000000cd617fcf9fd7ecd"}]} 

还可以在这里查看 API 客户端库:https://github.com/Paragraph1/php-fcm - Zuko

0

请参考以下代码

<?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;
 ?>

欢迎来到 StackOverflow。仅包含代码的答案通常会被标记为“低质量”并删除。请阅读有关回答问题的帮助部分,然后考虑添加一些评论到您的答案中。 - Graham

0

尝试下面的代码。我已经使用过它并且完美运行:

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

如果您仍然收到多个通知,则必须管理设备令牌。

每个设备可能有多个设备令牌。因此,您必须使用设备ID进行管理。按照以下步骤:

  1. 在注册设备令牌时,您必须将其与设备ID(设备ID和设备令牌的组合)进行检查。因此,在保存之前,请检查设备ID并相应地更新令牌,以便我们可以获得该设备的最新设备令牌。每个设备都有唯一的设备ID。

  2. 当用户登录时,注册设备令牌和设备ID。当用户注销时,只需使设备令牌为空即可。这样,下次我们就可以根据设备ID更新设备令牌。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接