ニフティクラウドmobile backendを利用すると、簡単にPush通知などを実装することができます。
Push通知の実装方法については、@yokoyamaさんが記事にしていますのでそちらを。
ハマったこと
Push通知の実装は簡単にできたのですが、アプリをインストールし直して以降、下記のようなエラーが発生しました。
com.nifty.cloud.mb.NCMBException: {"code":"E409001","error":"Duplication Error"}
この状態でもPush通知を受け取ることができるのですが、端末の情報をうまく登録できていないらしく、端末のobjectIdを取得するとnullが返ってくるようになりました。
原因
mobile backendのmBaaSのはまりやすいポイント徹底解説より「インスタレーション編」に、この問題について解説がありました。
objectIdはユニークですが、同時にデバイストークンについてもユニークなIDとなっています。各デバイスについてデータが登録済みであるかどうかはデバイストークンを使っています。そのため端末のキャッシュやデータを削除するだけでなく、管理画面からもデータを削除する必要があります。
前述の通りデバイストークンはユニークになっています。そのため重複して登録しようとするとE409001を返却します。
アプリをインストールし直した場合に、同じデバイストークンを登録しようとしてしまうために発生していたようです。
対応方法
mobile backendのmBaaSのはまりやすいポイント徹底解説より「インスタレーション編」にあるように、下記の処理を実装することで対応できます。
- E409001が発生したらNCMBQueryを使ってサーバ側から同一デバイストークンを持つオブジェクトを検索します。
- 取得したオブジェクトのobjectIdをcurrentInstallationに設定してfetchします。
Androidの実装例は下記のようになります。(アプリの再インストールを考慮した端末情報の登録より)
final NCMBInstallation installation = NCMBInstallation.getCurrentInstallation();
installation.getRegistrationIdInBackground("SENDER_ID", new RegistrationCallback(){
@Override
public void done(NCMBException e) {
if (e == null) {
try {
installation.save();
} catch(NCMBException le) {
if (NCMBException.DUPLICATE_VALUE.equals(le.getCode()))
// レジストレーションIDの重複エラー
// ユーザーによるローカルデータ削除や、アプリ再インストールがされた場合に発生。
// 以下、クラウド側に既登録の情報からローカルデータを復旧する処理。
NCMBQuery<NCMBInstallation> query = NCMBInstallation.getQuery();
query.whereEqualTo("deviceToken", installation.get("deviceToken"));
try {
NCMBInstallation prevInstallation = query.getFirst();
String objectId = prevInstallation.getObjectId();
installation.setObjectId(objectId);
installation.save();
} catch(NCMBException le2) {
le2.printStackTrace();
}
} else {
le.printStackTrace();
}
}
} else {
e.printStackTrace();
}
}
});
以上で、無事に端末を登録でき、objectIdを取得できるようになりました。