メッセージプッシュの場合、iOSはapnsを使用し、Androidはgcmを使用します。プッシュに失敗すると無効なトークンが返されますが、無効なトークンのうち、どれが禁止された通知でどれがアプリのアンインストールに起因するものかを区別できるでしょうか。
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 はエラーを報告せず、このトークンを無効または間違ったトークンとはみなしません。
アプリをアンインストールすると、次の判定が呼び出されます。statusCode は 8 に等しいです
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; }
したがって、apns はアンインストールによるプッシュの失敗を区別できるはずですが、通知を無効にすると応答しません
2 GCM エラー判定コード分析:
応答.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 つのメソッドはいずれもエラー トークンを書き込みません。つまり、通知が無効になっている場合、トークンも有効になり、エラーは返されません。
アプリがアンインストールされている場合は、getInvalidRegistrationIdsが実行され、$result['error']==NotRegisteredになります
このように、GCMがNotRegisteredを返した場合は、アンインストールによるエラーメッセージであり、通知が禁止されていることを意味します. GCM は、これを通常のトークンが発行されたものとして扱います。
上記のテストを通じて、apns と gcm は禁止通知を通常のトークンとして処理するのに対し、アプリをアンインストールすると無効なトークンとして扱われることがわかります。 (アンインストールして再インストールすると新しいトークンが生成されます)