消息推送ios用了apns,android用的是gcm。推送失敗都會返回無效的token,但是無效的tokne中,能不能區分到哪些是禁止通知,哪些是卸載app導致的呢?
1 APNS PHP 的推送返回錯誤處理
Push.php if (!empty($aMessage['ERRORS'])) {
foreach($aMessage['ERRORS'] as $aError) {
if ($aError['statusCode'] == 0) {
$this->_log("INFO: Message ID {$k} {$sCustomIdentifier} has no error ({$aError['statusCode']}), removing from queue...");
$this->_removeMessageFromQueue($k);
continue 2;
} else if ($aError['statusCode'] > 1 && $aError['statusCode'] <= 8) {
$this->_log("WARNING: Message ID {$k} {$sCustomIdentifier} has an unrecoverable error ({$aError['statusCode']}), removing from queue without retrying...");
$this->_removeMessageFromQueue($k, true);
continue 2;
}
}
if (($nErrors = count($aMessage['ERRORS'])) >= $this->_nSendRetryTimes) {
$this->_log(
"WARNING: Message ID {$k} {$sCustomIdentifier} has {$nErrors} errors, removing from queue..."
);
$this->_removeMessageFromQueue($k, true);
continue;
}
}
通過禁止通知,apns不會報錯,不會將這個token當成無效或錯誤的token。
卸載app,會調用到以下判斷,statusCode等于8if ($aError['statusCode'] > 1 && $aError['statusCode'] <= 8) {
$this->_log("WARNING: Message ID {$k} {$sCustomIdentifier} has an unrecoverable error ({$aError['statusCode']}), removing from queue without retrying...");
$this->_removeMessageFromQueue($k, true);
continue 2;
}
因此,apns應該是可以區分卸載導致的推送失敗,但是禁止通知則無法反應
2 GCM的錯誤判斷代碼分析:
Response.class.php/**
* Returns an array containing invalid registration ids
* They must be removed from DB because the application was uninstalled from the device.
*
* @return array
*/
public function getInvalidRegistrationIds()
{
if ($this->getFailureCount() == 0) {
return array();
}
$filteredResults = array_filter($this->results,
function($result) {
return (isset($result['error'])
&& (($result['error'] == "NotRegistered") || ($result['error'] == "InvalidRegistration")));
});
return array_keys($filteredResults);
}
/**
* Returns an array of registration ids for which you must resend a message (?),
* cause devices aren't available now.
*
* @TODO: check if it be auto sended later
*
* @return array
*/
public function getUnavailableRegistrationIds()
{
if ($this->getFailureCount() == 0) {
return array();
}
$filteredResults = array_filter($this->results,
function($result) {
return (
isset($result['error'])
&&
($result['error'] == "Unavailable")
);
});
return array_keys($filteredResults);
}
如果禁止通知,上述2個方法都不會寫入錯誤token,也就是說禁止通知,token也是有效的,且不會返回錯誤。
如果是卸載app,則會執行到getInvalidRegistrationIds,且$result['error']==NotRegistered
這樣,GCM如果返回的是NotRegistered,則說明是卸載產生的錯誤信息,而禁止通知,GCM是當成正常token發出去的。
通過以上測試,說明apns和gcm對禁止通知都是當成正常token來處理的,而卸載app則會當成無效的token。(卸載后重裝的話,會生成新的token)