プッシュ通知
monaca
NCMB
MonacaDay 22

MonacaアプリのイベントとNCMBの関係

ちょうどハマったので共有を。

Monacaアプリを作る際にはJavaScriptを使いますが、動かすときには幾つかのイベントがあります。主なものとして以下があります。

  • deviceready
  • DOMContentLoaded
  • ons.ready

devicereadyはアプリが動作できる状態になり、プラグインの呼び出しが可能になった時に呼ばれます 。それに対して DOMContentLoaded はDOMの読み込みが完了したタイミングで呼ばれます。devicereadyはDOMContentLoadedより後に呼ばれるようです。ons.readyはさらにOnsen UIの画面構築まで完了したタイミングで呼ばれるイベントです。

devicereadyはアプリ、つまりiOSやAndroid環境でしか呼ばれないためにMonaca IDEのプレビュー表示では呼ばれないイベントになります。そのため、つい DOMContentLoaded を使ってしまいます。

そして本題なのですが、DOMContentLoadedのタイミングではプラグインが使えない状態なので、ニフクラ mobile backendのプッシュ通知のデバイストークン登録に失敗します。

NCMB.monaca.setDeviceToken(
  applicationKey,
  clientKey,
  senderId,
  function() {
    alert('Registerd.');
    NCMB.monaca.getInstallationId((id) => {
      alert("installationID is: " + id);
    });
  },
  function(err) {
    alert(JSON.stringify(err));
  }
);

動かすためには deviceready で実行する必要があります。

解決策

プレビューでも動いてプッシュ通知のデバイストークン登録もできるようにするには実機動作かどうかを判断するのが良さそうです。

const event = window.cordova ? 'deviceready' : 'DOMContentLoaded';
document.addEventListener(event, () => {
  // この中で処理
});

ons.ready を使っている場合はこういった問題は発生しないでしょう。

ons.ready(() => {

});

試していないですが、 jQueryの $(function() {});$(document).ready(function(){}); と同じで、ドキュメントが準備完了になった段階で呼ばれるのでプラグインが使えるとは限りません。同じ問題が発生する可能性があります。スマートフォンアプリを作っているのでちゃんと deviceready を使いましょう。