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

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

Monacaとニフクラ mobile backendを使って勤怠管理アプリを作ろう【その3:データをファイルストアに保存する】

f:id:mbaasdevrel:20200915152727p:plain

Monacaを使えば、誰でも簡単にスマートフォンアプリが開発できます。さらにそこにニフクラ mobile backendを組み合わせることで、データの保存や認証などのサーバが必要な機能をすばやく追加できます。

この連載記事では業務でよくある勤怠管理(出退勤入力)アプリを作るのを目標としています。全部で3回に分けて開設します。

  1. 認証機能を実装する
  2. データの保存と表示処理を実装する
  3. データをファイルストアに保存する

第3回目となる今回は、データをファイルストアに保存する(バックアップする)機能を解説します。

前回の記事はこちらです。 Monacaとニフクラ mobile backendを使って勤怠管理アプリを作ろう【その2:データの保存と表示処理を実装する】 - ニフクラ mobile backend(mBaaS)お役立ちブログ

バックアップの目的は

業務システムではデータを締めて更新できないようにするということがよく行われます。経理や人事などバックオフィス系でよく行われる処理です。これによって過去データが改ざんできないようにしたり、保全が可能になります。

今回はそこまで厳しくありませんが、勤務データをデータストアからファイルストアへ移しておくことで、いつでも参照できるデータとして役立てられるようになるでしょう。

スクリプト機能を利用する

データストアからファイルストアへデータをコピーする処理を、mBaaSのスクリプト処理で実現します。mBaaSにはタイマー機能はありませんが、Google Apps Scriptや社内のサーバなどから定期的に呼び出せば、自動的にバックアップが作成される仕組みです。

まず csv.js というファイルを作成します(ローカルコンピュータ上です)。初期の内容は次のようにします。

const NCMB = require('ncmb');

module.exports = async function(req, res) {
  try {
    // 1. mBaaSの初期化処理

     // 2. 管理者ユーザーでログイン

    // 3. 変数の準備
    // 処理対象の日付
    const d = req.query.date ? new Date(req.query.date) : new Date;
    // 処理対象の日付の00:00を取得
    const startDate = new Date(`${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()} 00:00:00 UTC+0900`);
    // 処理対象の日付の次の日(00:00)を取得
    const endDate = new Date(`${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()} 00:00:00 UTC+0900`);
    // 保存するファイル名を、日付を元に設定
    const fileName = `working-${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}.csv`;
    d.setDate(d.getDate() + 1);

    // 4. データストアの検索

    // 5. CSV化

    // 6. ファイルストアへの保存

    // 7. 処理完了
    res.send('Uploaded');
  } catch (err) {
    // エラー
    res.send(JSON.stringify(err));
  }
}

1. mBaaSの初期化処理

Monacaアプリと同じように、まず最初にmBaaSを初期化します。アプリケーションキーとクライアントキーは、個人のものと書き換えてください。

const applicationKey = 'YOUR_APPLICATION_KEY';
const clientKey = 'YOUR_CLIENT_KEY';
const ncmb = new NCMB(applicationKey, clientKey);

2. 管理者ユーザーでログイン

管理ユーザは第1回目の記事で作成してもらったユーザになります。ユーザ名とパスワードをそれぞれ書き換えてください。

await ncmb.User.login('ADMIN_USER_NAME', 'ADMIN_PASSWORD');

3. 変数の準備

今回必要な変数は次の4つになります。それぞれ日付(d)を基本としています。dはクエリパラメータのdateで変更できます(デフォルトは今日の日付です)。こちらは記述済みです。

  • d
    処理対象の日付
  • startDate
    処理対象の日付の00:00
  • endDate
    処理対象の日付の次の日(00:00)
  • fileName
    保存するファイル名。日付を元に設定

4. データストアの検索

データストアのクラス、Recordを検索します。 include を使うと、別なデータストアのクラスデータ(ポインタ)を一緒に取得できます。そして対象データを createDate の処理対象日以上と、処理対象日の次の日未満の2つで絞り込みます。

const ary = await ncmb.DataStore('Record');
  // ユーザデータも一緒に取得します
  .include('user')
  // 勤務時間が入っているものだけ
  .equalTo('working', false)
  // 処理対象日時(00:00)以上
  .greaterThanOrEqualTo('createDate', startDate)
  // 処理対象日時の次の日(00:00)未満
  .lessThan('createDate', endDate)
  // 最大1000件(mBaaSの最大取得件数)
  .limit(1000)
  .fetchAll();

5. CSV化

取得したデータをCSV化します。そのために、必要なデータを配列に入れていきます。mBaaSではデータの取得は get メソッドを使います。また、日付は直接日付データが入っていません。 {"_type": "Date", "iso": (日付)} という形になっていますので注意してください。

const csv = [];
const columns = ['objectId', 'time', 'name', 'startAt', 'endAt'];
csv.push(columns.map(c => `"${c}"`).join("\t"));
for (let row of ary) {
  const params = [
    row.get('objectId'),
    row.get('time').iso,
    Object.keys(row.get('user')).length > 0 ? row.get('user').name.replace(/"/g, '""') : '',
    new Date(row.get('time').iso).toLocaleString(),
    new Date(new Date(row.get('time').iso).getTime() + row.get('workingTime')).toLocaleString()
  ];
  csv.push('"' + params.join("\"\t\"") + '"');
}

6. ファイルストアへの保存

CSVのデータができあがったら、ファイルストアに書き込みます。Bufferを使って文字列をBufferにしたら、それをファイル名とともに File.upload メソッドに適用します。これでファイルストアへのアップロード処理が完了です。

// 6. ファイルストアへの保存
const buf = Buffer.from(csv.join("\r\n"), 'UTF-8');
await ncmb.File.upload(fileName, buf);

スクリプトをアップロードする

csv.js ができあがったら、ファイルを管理画面からアップロードしましょう。

f:id:mbaasdevrel:20200915152727p:plain

今回は次のように指定してください。

  • メソッド
    GET
  • ファイルの状態
    実行可能

ほかは元のままで大丈夫です。そしてアップロードするボタンを押します。しばらく(1分程度)待つと、実行可能になります。

テストで実行する

では管理画面で実行してみます。スクリプトの一覧からcsv.jsを選んでください。

f:id:mbaasdevrel:20200915152744p:plain

実行タブを選択して、Queryを date=2020-09-10 とします(日付は今日の日付にしてください)。

実行ボタンを押すと確認が出ますので、実行するボタンを押します。処理がうまくいけば uploaded という文字列が返ってきて、さらにファイルストアに working-2020-09-10.csv といったCSVファイルが保存されているはずです。

f:id:mbaasdevrel:20200915152806p:plain

定期実行について(ハンズオン対象外)

もし自社内にサーバがあれば、次のようなコードでスクリプトを実行できます。これは Node.js で書いていますので、サーバ上にNode.jsやNCMBのJavaScript SDKが必要です。今回のハンズオンでは対象外としています。

const NCMB = require('ncmb');

const applicationKey = 'YOUR_APPLICATION_KEY';
const clientKey = 'YOUR_CLIENT_KEY';
const ncmb = new NCMB(applicationKey, clientKey);

(async () => {
  const res = await ncmb.Script
    .query({date: '2020-09-10'}) // 日付は適当なものを指定してください
    .exec('GET', 'csv.js');
  console.log(res.body);
  // 処理がうまくいけば uploaded と出力されます
})();

定期実行については Google Apps Scriptのタイマートリガーと、Google Apps Script用のSDKを組み合わせても実現できます。

Google Apps Scriptのトリガーを使ってスクリプトを自動テストする - ニフクラ mobile backend(mBaaS)お役立ちブログ

まとめ

今回のハンズオンでは次の4つの機能を利用しました。

  1. 会員管理(匿名認証)
  2. データストア(データの保存、検索)
  3. ファイルストア(アップロード)
  4. スクリプト

これらはmBaaSを使いこなす上での基本機能ともいえます。触れなかったのはプッシュ通知くらいでしょう。ぜひmBaaSを使いこなして、皆さんの業務アプリ開発に役立ててください。

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。