PHPサーバー側とAndroidクライアント側アプリケーションがあるシステムがあります。 AndroidはWebサービス経由でパラメータを送信し、PHPはGCM側を処理します。 PHPはプッシュ通知を送信し、送信前にDBからすべての登録IDを取得します。問題は、同じデバイスが2つ以上のregistrationidを持つ可能性があるということです。このため、プッシュ通知は2回以上同じデバイスに送信されました。この問題を処理するソリューションはありますか?Android GCM 1つのデバイスに複数の登録IDがあります
答えて
データベース内の各デバイスにユニークIDを格納するだけで済みます。次に、すべてのデバイスに対してプッシュ通知を1回だけ送信できます。
同じデバイスで複数の登録IDが表示されることはありません。奇妙なこと。
登録IDの更新を正しく管理しましたか?
あなたの問題は、デバイスから登録IDを取得する方法だと思います。 regIDを1回送信する必要があります。また、GCMサーバーがリフレッシュを要求するときには、regIDをWebサーバーに再送信して保存し、古いredIDを上書きする必要があります。 アンドロイド参照のthisを参照してください。
ありがとうございますが、主な問題は更新しようとしていません。 scenerioでは、ユーザーは多くのアンドロイドデバイスを持つことがあります。このため、3つのデバイスには7つのregistrationIdがあります。私は3プッシュメッセージを送信したいが、GCMは7を送信する。 – iravul
あなたは私の応答を理解していない...すべてのデバイスで、Google GCMサーバーは定期的にIDを更新したい...アンドロイドのAPIドキュメントをチェックする...エラーは最初です:各デバイスは1つのregIDを時間内に持つ必要があります。 – trullallero
GCMはregistrationIdを変更することができ、サーバー側で更新する必要があります。
- メッセージを送信すると、デバイスに使用される新しいregistrationIdが結果に含まれる可能性があります。そのため、新しいregistrationIdを更新する必要があります。
ルックMESSAGE_IDが設定されている場合、REGISTRATION_IDをチェックlink at Interpreting a success response section
この:REGISTRATION_IDが設定されている場合は、サーバーのデータベースに新しい値(正規のID)と、元のIDを交換してください。元のIDは結果の一部ではないので、リクエストで渡されたregistration_idsのリストから取得する必要があります(同じインデックスを使用)。
ありがとうございますが、主な問題は更新しようとしていません。 scenerioでは、ユーザーは多くのアンドロイドデバイスを持つことがあります。このため、3つのデバイスには7つのregistrationIdがあります。 3プッシュメッセージを送信しますが、GCMは7を送信します。 – iravul
GCMサービスでは、1つのregistrationIdによってデバイス/アプリケーションが識別されるため、GCMを使用して3つのデバイスがサーバーに接続されている場合は3つのregIdが必要です。 regIdが 'GCMRegistrar.getRegistrationId'にまだ保存されている場合は、' GCMRegistrar.register'の前にチェックしてください。必要以上に生成しています。 – AlexBcn
GCMチェック端末(bbb)を送信し、user2またはuser1がこの通知を受け取らない場合、(terminal1)gcm(bbb)を変更した場合、(terminal1)gcm(aaa)login user1およびuser2。誤解! – delive
時々、Googleが登録IDを変更すると、複数のIDが関連付けられます。通知(あなたのサーバー)を送信するサーバーは、新しいIDでデータベースを更新する必要があります。詳細情報については
はこの文書を確認してください。
http://developer.android.com/google/gcm/adv.html
を彼らは言う:
それは、限り、アプリケーションがうまく動作しているように、すべてサーバー側では正規のID
です正常に動作するはずです。ただし、アプリケーションのバグによって同じデバイスの複数の登録がトリガーされると、状態を調整するのが難しくなり、重複するメッセージに終わる可能性があります。
GCMは、これらの状況から簡単に回復するための「正規登録ID」と呼ばれる機能を提供します。正規登録IDは、アプリケーションによって要求された最後の登録のIDであると定義されています。これは、サーバーがメッセージをデバイスに送信する際に使用するIDです。
後で別の登録IDを使用してメッセージを送信しようとすると、GCMは通常どおりリクエストを処理しますが、レスポンスのregistration_idフィールドに正式な登録IDが含まれます。サーバに保存されている登録IDをこの標準IDに置き換えてください。使用しているIDが機能しなくなります。
私は同じデバイス上の2つの異なる登録IDで問題に直面していますが、0のcanonical_idsが戻ります。 – neobie
プッシュレスポンスで標準的なIDを取得します。古いIDを新しい正準IDで更新する必要があります。
解決策がもう1つあります。パッチに似ています。 GCMリクエストのJSONでパラメータ 'dry_run'を渡すことができます。これをtrueに設定すると、デバイスIDに偽のメッセージが送信され、応答が生成されます。
デバイスにはメッセージは表示されませんが、応答が得られるため、結果にregistration_idが含まれているデバイスIDを確認してデータベースから削除できます。
$fields = array(
'registration_ids' => $deviceId,
'data' => array("message" =>'fake_message'),
'dry_run'=>true
);
希望します。
ここにこの問題の解決策を示します。あなたはGCM通知を送信するとき あなたは、配列内のこの
Array
(
[multicast_id] => 12345678910
[success] => 8
[failure] => 3
[canonical_ids] => 4
[results] => Array
(
[0] => Array
(
[error] => NotRegistered
)
[1] => Array
(
[message_id] => 0:1412242641156904%3dc89e2df9fd7ecd
)
[2] => Array
(
[registration_id] => APA91bH3WdWwqFCVKbvZXsf-gj28iWU5oYbSCRZYFp987CHasxwT_HOiE7dp8212XID0FMGVG2n4NLohFsEGYJ-LEA07xsgsKfT00xModQcx5QgTBmJtxlWgeaWFpz29z-iCPYbvOHEhqfwHmN-HIps7DiWntcs-Qg
[message_id] => 0:1412242641155639%3dc89e2df9fd7ecd
)
[3] => Array
(
[registration_id] => APA91bH3WdWwqFCVKbvZXsf-gj28iWU5oYbSCRZYFp987CHasxwT_HOiE7dp8212XID0FMGVG2n4NLohFsEGYJ-LEA07xsgsKfT00xModQcx5QgTBmJtxlWgeaWFpz29z-iCPYbvOHEhqfwHmN-HIps7DiWntcs-Qg
[message_id] => 0:1412242641155809%3dc89e2df9fd7ecd
)
[4] => Array
(
[message_id] => 0:1412242641157971%3dc89e2df9fd7ecd
)
[5] => Array
(
[registration_id] => APA91bGXo_gnfBZsvPoqJTYy1BWz0FQIkwlD1EmBtcxgWWfceYvd0ehWqVCtfd8n56VGYrvXCS2v48kTiA69BD7Sci0BA9a9bKTIg_MUEnDd79ssCK-miPG88DDGL4oKtB14cPbh-_xbgVRZllMOzwNZf_w5uJGR8g
[message_id] => 0:1412242641157969%3dc89e2df9fd7ecd
)
[6] => Array
(
[registration_id] => APA91bGXo_gnfBZsvPoqJTYy1BWz0FQIkwlD1EmBtcxgWWfceYvd0ehWqVCtfd8n56VGYrvXCS2v48kTiA69BD7Sci0BA9a9bKTIg_MUEnDd79ssCK-miPG88DDGL4oKtB14cPbh-_xbgVRZllMOzwNZf_w5uJGR8g
[message_id] => 0:1412242641157967%3dc89e2df9fd7ecd
)
)
)
のような応答がuは今、すべてを行う必要があり、4人のユーザーが新しいGCM IDを生成している持っていることを意味している4であるインデックスcanonical_ids
あり得ます次にgcm通知を送信したときに、gcmidを上記の配列で受け取った新しいものに置き換えてください。
私のPHPアプリケーションはcodeigniterフレームワーク上に構築されていますので、ここで私が行ったことです。 私は、ログインと呼ばれるモデルを持っており、そこに私は、アレイ
function getAllRegIds(){
$query = "SELECT gcmid,id FROM users_app WHERE gcmid IS NOT NULL AND gcmid != '' GROUP BY gcmid"; //group by incase a user loggedin with multiple userids in your a
$query = $this->db->query($query);
if($query->num_rows() > 0){
$result = $query->result_array();
$regids = array();
foreach($result as $row){
$regids[$row['id']] = $row['gcmid'];
}
return $regids;
}else{
return false;
}
}
のインデックスが配列のこの
Array(
[29] => APA91bEYda3DVb...
[1] => APA91bF0yfdZjX4...
[12] => APA91bG-9fsBGT-...
[11] => APA91bGNRh_VWF...
[3] => APA91bGXo_gnfBZ...
[2] => APA91bH3WdWwqFC...
[26] => APA91bHn8Ufwe4...
)
のように見えるように、ユーザーのユーザーIDとともにデータベースからgcmidsを返す関数を持っています
指数は、ここで、この機能は、コントローラの関数内で呼び出された値gcmid
を持つユーザーIDで実装
public function sendtoall(){
$this->load->model('app/login');
$result = $this->login->getAllRegIds(); //here i got all gcmids with userids as index
$message = $this->input->post('message');
$chunks = array_chunk($result,1000); //broken the array into chunks of 1000 ids because gcm can only send message to 1000 ids at a time
$status = $this->sendNotification($chunks,$message);
if(!empty($status) && is_array($status)){
foreach($status as $key=>$row){
if(array_key_exists('canonical_ids',$row) && $row['canonical_ids'] > 0){
$canonical_ids = $row['canonical_ids'];
if(array_key_exists('results',$row) && !empty($row['results']) && is_array($row['results'])){
foreach($row['results'] as $k=>$v){
if(array_key_exists('registration_id',$v)){
$userid = array_search($chunks[$key][$k], $result);
$newgcmid = $v['registration_id'];
$this->login->updateGCMId($userid,$newgcmid);
}
}
}
}
}
}
echo json_encode($status);
}
です
あなたのコメントで私は配列を1000個の塊に分割しました。なぜなら、gcmは一度に1000個のメッセージにメッセージを送ることができ、sendNotification
という関数を呼び出し、gcmが受け取った応答を返します。すべての標準的なIDを持ちます。
ステータスが空でなく、配列であるならば、私はその後、
以下sendNotification
実装を参照してください、私は1000年、IDSのチャンクに通知を送信していますので、それが複数の応答配列を有することができるので、状況をforeachのチェックそれがインデックスcanonical_ids
を持っていて、0より大きいかどうかチェックされます。つまり、置き換えが必要なIDがある場合、インデックスがresult
で、空ではなく配列であるかどうかがチェックされます。
foreachのresult
及びこれらのIDを意味し、それにregistration_id
率を有するこれらのインデックスのキーと値を取得するには、私たちのデシベル
gcmid
ニーズによって交換するユーザーのuserid
を得るに交換する必要がありますユーザーのoldgcm IDで、result
配列を検索
($chunks[$key][$k]
、最初のパラメータは、必要なgcmid
と第二を持っているチャンクのキーはそのgcmid
のindex
である)新しいgcmid
からの取得results
アレイ
モデル関数updateGCMId
を呼び出し、userid
とnewgcmid
を渡します。
ここでは、sendNotification
とupdateGCMId
の機能が実装されています。
private function sendNotification($regids,$message){
$status = array();
$result = $regids;
if($result){
foreach($result as $thousandids){
$registatoin_ids=$thousandids;
$msg=array("message"=>$message);
$url='https://android.googleapis.com/gcm/send';
$fields=array
(
'registration_ids'=>$registatoin_ids,
'data'=>$msg
);
$headers=array
(
'Authorization: key=AIza..............',
'Content-Type: application/json'
);
$ch=curl_init();
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_SSL_VERIFYPEER,false);
curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode($fields));
$result=curl_exec($ch);
curl_close($ch);
$result = json_decode($result,1);
$status[] = $result;
}
}
return $status;
}
update
機能:
public function updateGCMId($userid,$gcmid){
$query = 'UPDATE users_app SET
gcmid = "'.$gcmid.'"
WHERE id = "'.$userid.'"';
$this->db->query($query);
}
は最後にDuplicate Registration Idのための作業溶液を得ました。既存の登録IDを標準IDで更新することに関するすべてです。
Androidスタジオでテンプレートから生成されたバックエンドに付属するGoogleのサンプルコードがこれを行います。 MessageEndpointクラスをチェックすると、正規のIDをチェックしていることがわかります。存在する場合は、regidが変更されているため、その特定のデバイスに対して理想的に更新する必要があるということです。
public void sendMessage(@Named("message") String message) throws IOException {
if (message == null || message.trim().length() == 0) {
log.warning("Not sending message because it is empty");
return;
}
// crop longer messages
if (message.length() > 1000) {
message = message.substring(0, 1000) + "[...]";
}
Sender sender = new Sender(API_KEY);
Message msg = new Message.Builder().addData("message", message).build();
List<RegistrationRecord> records = ofy().load().type(RegistrationRecord.class).limit(10).list();
for (RegistrationRecord record : records) {
Result result = sender.send(msg, record.getRegId(), 5);
if (result.getMessageId() != null) {
log.info("Message sent to " + record.getRegId());
String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// if the regId changed, we have to update the datastore
log.info("Registration Id changed for " + record.getRegId() + " updating to " + canonicalRegId);
record.setRegId(canonicalRegId);
ofy().save().entity(record).now();
}
} else {
String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
log.warning("Registration Id " + record.getRegId() + " no longer registered with GCM, removing from datastore");
// if the device is no longer registered with Gcm, remove it from the datastore
ofy().delete().entity(record).now();
} else {
log.warning("Error when sending message : " + error);
}
}
}
}
- 1. GCM登録IDの有効期限はありますか?
- 2. C2DMで複数のAndroidデバイスを登録すると、複数の登録IDが表示されます
- 3. WSO2 2.0.1 Androidデバイスの登録にエラーがありますか?
- 4. 複数のデバイスに登録するSQLite - Android
- 5. TinyIoC:1つのインスタンスに複数のインターフェイスを登録します。
- 6. GCM登録IDが変更されました
- 7. C2DMのアプリケーションID、登録ID、デバイスIDの長さ
- 8. GCM GCMとサードパーティのサーバーでデバイスを登録解除する方法
- 9. Androidのc2dm登録IDフォーマット
- 10. GCM登録IDをMySQLに一意に保存する方法
- 11. GCMを使用してサーバー上で登録解除するデバイスIDを検出する方法Androidプッシュ
- 12. Android-Blackberry GCM:移植されたアンドロイドアプリをGCMサービスに登録できません
- 13. Android GCM一部の端末が登録されていない
- 14. デバイスがオフネットワークのときの登録ID C2DMの更新
- 15. 複数のGoogle AnalyticsトラッキングIDが1ページにありますか?
- 16. Android C2DM登録IDリフレッシュ
- 17. 複数のアプレットが1つのjarファイルにあり、複数のアプレットが1ページにありますか?
- 18. 1つの列に複数の変数がありますか?
- 19. 毎回アプリケーションの開始時にGoogle Cloud Messaging(GCM)の登録IDをリクエストする
- 20. 1つのパッケージに複数のアイコンがありますか? Android - Eclipse開発
- 21. Android GCMエラーです。クライアントが登録されている場合、サーバは登録されていません
- 22. Gcm iOS、トピックに登録、エラーコード3004
- 23. vscodeの1つのキーボードショートカットに複数のアクションがあります
- 24. Android C2DM登録IDの妥当性
- 25. django登録 - 複数のユーザーに電子メールIDを許可
- 26. 1つのドメインに複数のCookieがありますか?
- 27. 1つのアプリケーション内に複数のマスターページがあります
- 28. spring:1つのPOST内に複数のパラメータがあります
- 29. 1つのスパーク内に複数のテキストカラーがあります:TextInput
- 30. エラー:1つの宣言に複数の型があります
ありがとうございますが、主な問題は更新しようとしていません。 scenerioでは、ユーザーは多くのアンドロイドデバイスを持つことがあります。このため、3つのデバイスには7つのregistrationIdがあります。私は3プッシュメッセージを送信したいが、GCMは7を送信する。 – iravul