Android
iOS
mBaas

ニフティクラウドmobile backendを利用するときの注意点

More than 3 years have passed since last update.

ニフティクラウド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のはまりやすいポイント徹底解説より「インスタレーション編」にあるように、下記の処理を実装することで対応できます。

  1. E409001が発生したらNCMBQueryを使ってサーバ側から同一デバイストークンを持つオブジェクトを検索します。
  2. 取得したオブジェクトの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を取得できるようになりました。