ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

プッシュ通知を承認制にする【データメンテナンス機能を作る】

プッシュ通知は従来のマーケティング手法で言えばメールマーケティングに相当します。つまり一度配信してしまうと、後から取り消すのが難しい拡散方法ということです。そのため企業によっては一旦承認フローを経てからプッシュ通知を送りたいという要望も聞かれます。

そこで独自のプッシュ通知管理画面を作成して、承認フローを経るようにしてみたいと思います。作成していく過程をステップを踏んで説明していきますので、自社のフローに合わせてカスタマイズしてみてください。

今回はデータメンテナンス画面の処理について紹介します。

実際の処理について

このWebアプリケーションはVue.jsで構築されています。機能はコンポーネント化されています。今回は承認者のデータメンテナンス機能を作りますので、モーダル表示を行います。

モーダル表示について

モーダル表示を行う際には、Contents Management System - ニフティクラウドmobile backendのモーダル表示をベースにします。このHTMLをベースにして、config_manager.vueというファイルのtemplateタグを作成します。

このHTMLはbodyタグの直下に生成されるのを前提としています。そこで、config_form.vueの承認者の管理ボタンを押した時に、Appの処理を呼び出すようにします。

module.exports = {
    :
  methods: {
    :
    showManagerModal: function(e) {
      this.$emit('showModal', 'configManager');
    }
  }
}

もちろんAppやmain_content.vueではイベントを購読しておきます。

<router-view :ncmb="ncmb" v-on:updateKeys="updateKeys" v-on:showModal="showModal"></router-view>

今後、モーダル表示は複数パターンが考えられますので、モーダルの種類(今回はconfigManager)を指定できるようにしておきます。

export default {
  name: 'app',
  data: function() {
    return {
      ncmb: ncmb,
      error: null,
      success: null,
      modal: null // 追加
    };
  },
    :
  methods: {
      :
    showModal: function(modal) {
      this.modal = modal;
    },
    closeModal: function() {
      this.modal = null;
    },
  },
  :
}

このように this.modal に文字列を入れるようにします。閉じる場合は this.modal = null にするだけです。

Appのテンプレート側では次のように記述します。modalがconfigManagerの時だけ表示します。

<template>
  <div>
    <config-manager 
      id="config-manager" 
      :ncmb="ncmb"
      v-on:errorMessage="errorMessage"
      v-on:successMessage="successMessage"
      v-on:closeModal="closeModal"
      v-if="modal == 'configManager'" 
    />
      :
  </div>
</template>

これでボタンを押した際にモーダルが表示されます。

モーダルを閉じる

次にモーダルを閉じる機能を実装します。これはAppにあるcloseModalを this.$emit で呼び出すだけです。なお、クリックだけでなくESCキーでも閉じられるようにしています。

module.exports = {
    :
  methods: {
    cancel: function(e) {
      if (typeof e == 'undefined' || e.type == 'click' || (e.type == 'keyup' && e.keyCode == 27)) {
        
      }else{
        return true;
      }
      this.$emit('closeModal');
    }
  }
}

データを読み出す

まず最初にデータストアからデータを読み込む部分を作ります。最初はデータはありませんが、その方がデータ登録後の処理が分かりやすくなります。これはDOMを生成した後の created イベントに対して作成します。

一覧の更新は他のメソッドからも使いますので、別メソッド化しておきます。order(並び順)カラムを使って並び順を指定します。データはそのまま this.managers の中に保存します。

module.exports = {
  props: ['ncmb'],
  data: function() {
    let data = {
      managers: []
    };
    return data;
  },
  created: function() {
    window.addEventListener('keyup', this.cancel);
    this.updateList();
  },
  methods: {
      :
    updateList: function() {
      let me = this;
      let Manager = this.ncmb.DataStore('Manager');
      Manager
        .order('order')
        .fetchAll()
        .then(results => {
          me.managers = results;
        })
        .catch(err => {
          me.$emit('errorMessage', "データの取得に失敗しました")
        })
    }
  }
}

承認者を追加する

次に承認者を追加するアクションです。これは this.managers に対してデータストアのインスタンスを追加するだけです。

addManager: function() {
  let Manager = this.ncmb.DataStore('Manager');
  let manager = new Manager;
  this.managers.push(manager);
}

承認者を保存する

承認者を保存するアクションは次のようになります。this.managersを保存する処理は非同期処理になりますので、Promise.allでまとめて処理するようにします。manage.objectIdの有無でupdateまたはsaveメソッドを実行します。保存成功時に実行するme.cancel()はモーダルを閉じるアクションです。

save: function(e) {
  let me = this;
  let promises = [];
  for (let i = 0; i < this.managers.length; i++) {
    let manager = this.managers[i];
    manager.set('order', i);
    promises.push(manager.objectId ? manager.update() : manager.save());
  }
  Promise.all(promises)
    .then(results => {
      me.$emit('successMessage', "承認者を登録しました");
      me.cancel()
    }, err => {
      me.$emit('errorMessage', "データの保存に失敗しました");
    })
},

チェックボックスをすべて付ける

モーダル上部にあるチェックボックスを有効にすると一覧のデータすべてのチェックボックスが有効になります。これは this.managers にある各データの checked を trueにすればOKです。

checkAll: function(e) {
  let managers = [];
  for (let i = 0; i < this.managers.length; i++) {
    let manager = this.managers[i];
    manager.checked = e.target.checked;
    managers.push(manager);
  }
  this.managers = managers;
},

HTML側は次のようになります。

<input type="checkbox" v-model="manager.checked">

承認者を削除する

承認者を削除する場合は this.managers のデータの中で checked が有効になっているデータを対象にします。こちらもすべて非同期処理になりますので、Promise.all を使って一括処理を行います。今回は削除処理を行った場合はリストを取得し直しています。

deleteManager: function() {
  let promises = [];
  let me = this;
  for (let i = 0; i < this.managers.length; i++) {
    let manager = this.managers[i];
    if (manager.checked) {
      promises.push(manager.delete());
    }
  }
  Promise.all(promises)
    .then(results => {
      me.updateList();
    }, err => {
      me.$emit('errorMessage', "データの削除に失敗しました");
    })
},

並び替える

最後にデータの並び替えです。今回は一つ上または下のデータと入れ替える形になっています。そこでHTML側から -1 (上げる)または +1 (下げる)を送るようにします。

<a type="button" class="btn" style="text-decoration:none;" @click="moveManager(manager, -1)">↑</a>
<a type="button" class="btn" style="text-decoration:none;margin-left:1px;" @click="moveManager(manager, 1)">↓</a>

そして対象になる承認者データを探し、それと一つ前または後ろのデータを入れ替えます。

moveManager: function(o_manager, order) {
  for (let i = 0; i < this.managers.length; i++) {
    let manager = this.managers[i];
    if (manager !== o_manager)
      continue;
    if (!this.managers[i + order])
      continue;
    Vue.set(this.managers, i, this.managers[i + order]);
    Vue.set(this.managers, (i + order), o_manager);
    return;
  }
}

一番上や下のデータの場合、入れ替え対象になるデータがない場合もありますので、チェックするようにします。後は配列のインデックスを指定してデータを差し替えればOKです。


ここまでの処理でマスタデータのメンテナンスができるようになりました。同じような操作でプッシュ通知に必要なデータメンテナンスを実現しましょう。

プッシュ管理のコードはNCMBMania/pushManager at v0.2にアップロードされています。実装時の参考にしてください。