【问题标题】:GCM canonical idGCM 规范 ID
【发布时间】:2013-03-27 18:21:20
【问题描述】:

当 1 个设备具有多个 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>?
  • 3 列。一个带regid,一个带app id(用于其他事情),第三个类型(ios或android)
  • regid 是根据 app id 分配唯一的。使用应用程序 ID 作为您的杠杆。
  • 我没有保存设备 ID。如果我错了,请纠正我,但这与注册 ID 不同,对吗?
  • @MarkMolina 是的,deviceId 与注册 ID 不同。设备 ID 存储在您的设备中,使您的设备全球唯一,而在此上下文中的注册 ID 是 GCM 服务器上的设备 + 应用程序的注册 ID。

标签: java android push-notification google-cloud-messaging


【解决方案1】:

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 delete 是该请求中的第二个注册 ID。

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

最后检查双精度值并删除完全重复的值。结果应该是一个包含 5 个 regid 的数组(或直接从数组中删除该索引,而不是替换为 MY_REG_ID_#)。

【讨论】:

    【解决方案2】:

    您包含的 GCM 响应表明您向两个注册 ID 发送了消息。在 GCM 服务中成功接收到两条消息。仅对于第二条消息,您才获得了规范的注册 ID。

    由于您发送的每个请求都会收到来自 Google 的响应,因此您应该知道在触发此响应的请求中向 Google 发送了哪些注册 ID。您必须删除的旧注册 ID 是该请求中的第二个注册 ID。

    【讨论】:

    • 我用一个例子添加了我自己的答案。不过,您的回答确实有帮助。谢谢。
    【解决方案3】:
    <?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);
    

    【讨论】:

    • 请详细说明您的答案,因为只有代码的答案不清楚。
    • 按照步骤操作。会一目了然,功能方法也说明步骤
    • 不清楚。人们不需要 XX 分钟来检查答案,毕竟这对他们来说毫无用处
    【解决方案4】:
    <?php
    
    // API access key from Google API's Console
    
    define( 'API_ACCESS_KEY', 'AIzaSyCa1vcyOF6UhM6cgvnwARBafmdl8haQo1Y' );
    $con=mysqli_connect("localhost","root","","bloodbank_master");
    $response = array();
    
    $q="SELECT `regester_id` FROM  `gcm`";
    $result1 = $con->query($q) ;
    if ($result1->num_rows > 0) {
    
    $response["users"] = array();
    
    while ($row = $result1->fetch_array(MYSQLI_BOTH)) {
        $user = array();
        $registrationIds = array($row[0]);
    
    
        $msg = array
        (
        'message'   => 'hieee',
        'title'     => 'Blood Bank',
        'subtitle'  => 'This is a subtitle. subtitle',
        'tickerText'    => 'Ticker text here...Ticker text here...Ticker text here',
        'vibrate'   => 1,
        'sound'     => 1,
        'largeIcon' => 'large_icon',
        'smallIcon' => 'small_icon'
        );
    
        $fields = array
        (
        'registration_ids'  => $registrationIds,
        'data'          => $msg
        );
    
        $headers = array
        (
        'Authorization: key=' . API_ACCESS_KEY,
        'Content-Type: application/json'
        );
    
        $ch = curl_init();
        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 );
        curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
        curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
        $result = curl_exec($ch );
        curl_close( $ch );
    
        echo $result;
        }
    } 
    else {
        $response["success"] = 0;
        $response["message"] = "No users found";
    }
    ?>
    

    【讨论】:

    • 嗨@Ranjit,仅代码的答案通常不受欢迎。事实上,你的回答是否回答了这个问题? (如果你的答案有一些附带的文字,我可能不需要问)......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    相关资源
    最近更新 更多