GCM 规范 ID

15

如果一个设备有多个 regid,GCM 将返回规范 ID 错误:

{"multicast_id":xxxx,"success":2,"failure":0,"canonical_ids":1,"results":[{"message_id":"xxxxx"},{"registration_id":"newest reg ID here","message_id":"xxxxxx"}]}

它显示了应由GCM使用的最新regid,但为什么没有显示您应该删除的regid(旧的)?我如何知道旧的regid是什么以及应从数据库中删除哪一个?


你是如何管理你的数据库的?你使用设备ID吗? - Shail Adi
我没有保存设备ID。如果我错了,请纠正我,但这与注册ID不同,对吧? - Mark Molina
@MarkMolina 是的,deviceId与注册ID不同。设备ID存储在设备内部,使您的设备具有全球唯一性,而在此上下文中的registrationID是GCM服务器上设备和应用程序的注册ID。 - Adil Malik
@MarkMolina 我认为存储设备ID也无法解决问题。如果您找到任何解决方案,请告诉我好吗?我也遇到了同样的问题。 - Adil Malik
@Adil Malik:检查答案 - Mark Molina
显示剩余2条评论
3个回答

8

Eran的回答是正确的,但我仍然觉得有些模糊。不过,多亏了他,我找到了解决办法。

假设这是你的回复:

{
   "multicast_id":xxxxx,
   "success":7,
   "failure":0,
   "canonical_ids":2,
   "results":[
      {
         "message_id":"0:xxx%xxxxx"
      },
      {
         "message_id":"0:xxx%xxxxx"
      },
      {
         "registration_id":"MY_REG_ID_1",
         "message_id":"0:xxx%xxxxx"
      },
      {
         "message_id":"0:xxx%xxxxx"
      },
      {
         "message_id":"0:xxx%xxxxx"
      },
      {
         "registration_id":"MY_REG_ID_2",
         "message_id":"0:xxx%xxxxx"
      },
      {
         "message_id":"0:xxx%xxxxx"
      }
   ]
}

您可以看到,7条消息中有2条是重复的。

这是我向服务器发送消息的方式:

$tokenResult = mysql_query("SELECT reg_ids FROM table_with_regids"); //
$i = 0;
while($row = mysql_fetch_array($tokenResult)) {

     $registrationIDs[$i] = $row['reg_ids'];
     $i++;
}

来自Eran的回答:

由于您每发送一次请求,就会从Google获得一次响应,因此您应该知道在触发此响应的请求中向Google发送了哪些注册ID。您需要删除的旧注册ID是该请求中的第二个注册ID。

这意味着数组$registrationIDs[]的索引25应分别替换为MY_REG_ID_1MY_REG_ID_2

最后检查重复值并删除完全重复的项。结果应该是一个具有5个注册ID的数组(或直接从数组中删除该索引,而不是用MY_REG_ID_#替换它)。


4
您发送的GCM响应表明您向两个注册ID发送了一条消息。两条消息都成功地在GCM服务中接收到。只有第二条消息您获得了一个规范的注册ID。
由于您每发送一个请求,就会从Google那里得到一个响应,因此您应该知道在触发此响应的请求中向Google发送了哪些注册ID。您需要删除的旧注册ID是该请求中的第二个注册ID。

我添加了自己的答案并附上了一个例子。不过你的回答确实帮了我很多。谢谢。 - Mark Molina

2
<?php

//ASSUME gcm_registration_table field
// id || registration_id || user_id || created_at || updated_at


// FIND CANONICAL IDS POSITION
function CanonicalIdPosition($gcm_response)
{
    $c_ids = array();
    foreach ($gcm_response['results'] as $k => $val) {
        if (isset($val['registration_id'])) {
            $c_ids[] = $k;
        }
    }
    if ($c_ids) {
        return $c_ids;
    } else {
        return false;
    }
}

// Find Duplicate registration Ids from Server Matchind to index position
function DuplicateRegIdFromRegistrationTable($canonical_ids)
{

    DB::query("SELECT registration_id FROM gcm_registration_table");
    $results = DB::fetch_assoc_all();
    $duplicate_reg_val = array();

// Match Position and Find Value
    foreach ($results as $key => $val) {
        if (in_array($key, $canonical_ids)) {
            $duplicate_reg_val[] = $val['registration_id'];
        }
    }

    return $duplicate_reg_val;
}

// update existing Duplicate registration id with New Canonical registration ids
function UpdateDuplicateRegIds($duplicateVal)
{

    foreach ($duplicateVal as $val) {
        $sql = "UPDATE gcm_registration_table SET registration_id = {$val} WHERE registration_id ={$val}";
// Some Yours Code...
    }
}

// Method to send Notification to GCM Server
function SendGcmNotification($registatoin_ids_from_table, $message, $gcm_api_key, $dry_run = false)
{

// Set POST variables
    $url = 'https://android.googleapis.com/gcm/send';

    $fields = array(
        'registration_ids' => $registatoin_ids,
        'data' => $message,
        'dry_run' => $dry_run
    );

    $headers = array(
        'Authorization: key=' . $gcm_api_key,
        'Content-Type: application/json'
    );

//print_r($headers);
// Open connection
    if (!class_exists('curl_init')) {
        $ch = curl_init();
    } else {
        echo "Class Doesnot Exist";
        exit();
    }


// 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));
        return false;
    } else {
        return json_decode($result, true);
    }

// Close connection
    curl_close($ch);
}


//This Wont Send Notification to Device but gives you response to remove canonical ids
$gcm_response = SendGcmNotification($registatoin_ids_from_table, $message, $gcm_api_key, $dry_run = true);

$canonical_ids = CanonicalIdPosition($gcm_response);

if ($canonical_ids) {
    $duplicate_ids = DuplicateRegIdFromRegistrationTable($canonical_ids);
    UpdateDuplicateRegIds($duplicate_ids);
}

// Finally Get updated Registration Ids from table and send to GCM Server with
$gcm_response = SendGcmNotification($registatoin_ids_from_table, $message, $gcm_api_key, $dry_run = false);

2
请详细阐述您的答案,因为仅有代码的回答并不清晰。 - Mark Molina
按照步骤进行。这样做会很清晰,函数方法也会解释每个步骤。 - Raghu
这并不清楚。人们没有时间花XX分钟去检查那些最终对他们来说可能是无用的答案。 - Srneczek

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