今回はAWS Mobile Hubに含まれるサービスの一つ、ファイルストレージとMonacaアプリを連携します。AWS Mobile HubのファイルストレージにはS3が使われています。

プロジェクトの準備

第一回目の記事 で作成したプロジェクトにファイルストレージ機能を追加していきます。

ファイルストレージの有効化

AWS Mobile Hubのコンソール で、プロジェクトにUser File Storage を追加します。

「Store files」を選択して、保存します。

設定をローカルのMonacaプロジェクトに反映します。wwwディレクトリ内で、awsmobile pull コマンドを実行するとファイルストレージ機能が使えるようになります。

$ awsmobile pull

retrieving the latest backend awsmobile project information
awsmobile project's details logged at: awsmobilejs/#current-backend-info/backend-details.json
awsmobile project's access information logged at: awsmobilejs/#current-backend-info/aws-exports.js
awsmobile project's access information copied to: src/aws-exports.js
awsmobile project's specifications logged at: awsmobilejs/#current-backend-info/mobile-hub-project.yml
contents in #current-backend-info/ is synchronized with the latest in the aws cloud
? sync corresponding contents in backend/ with #current-backend-info/ Yes

これでAWS Mobile Hubの設定は完了です。

S3の設定を変更する

Monacaアプリからファイルをアップロードするには、S3の設定変更が必要です。
S3のコンソール にアクセスすると、xxxxx-userfiles-mobilehub-99999 といった名前のバケットが作成されています。
それを開き、アクセス権限設定の中にある「CORSの設定」を開きます。

例えば以下のように記述すると任意のホストからGET/POST/PUTアクセスが許可されます。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

さらに「バケットポリシー」を変更してGETアクセス可能にします。

リソース名はご自身の環境に合わせて変更する必要がありますので注意してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::xxxxx-userfiles-mobilehub-99999/public/*"
        }
    ]
}

この二つの設定を行うことでファイルのアップロードと表示が可能になります。

Monacaアプリの実装

src/app.js

AWS Amplifyから「Storage」モジュールを取得しておきます。

import Amplify, { Storage } from 'aws-amplify';
window.Storage = Storage;

save-data.html

Onsen UIでファイルをアップロードする画面を作ります。アップロード後、ons-cardの中に画像を表示します。

<ons-page>
  <input type="file" id="file" />
  <ons-card>
    <img id="image" />
  </ons-card>
  <script>
  </script>
  <style>
    #image {
      width: 100%;
    }
  </style>
</ons-page>

次に <script> タグ内に処理を記述します。<input type="file"> でファイルを選択したタイミングでアップロード処理を行います。 S3への保存は Storage.put メソッドで実行します。

ons.getScriptPage().onInit = function() {
  const me = this;
  // ファイルを選択したらイベント実行
  this.querySelector('#file').onchange = (e) => {
    // 選択したファイル
    const file = e.target.files[0];
    // ファイル名
    const key = file.name;
    // S3に保存
    Storage.put(key, file).then(e => {
      const url = `https://s3.amazonaws.com/${Storage._options.bucket}/public/${key}`;
      me.querySelector('#image').src = url;
    });
  };
};

なお、保存が完了した際の返り値の中にファイルの保存先URLはなかったため、若干複雑なURL生成処理を行っています。

実行結果の確認

選択されたファイルがアップロードされ、画面上に表示されます。

アップロードされたファイルは S3のコンソールpublicフォルダの中に格納されています。

配信を高速化する

Amazon S3はCloudfrontに対応していますので、設定を行うことでCDN配信が可能になります。その場合には表示用のURLが上記のコードとは異なりますのでご注意ください。

まとめ

S3の設定などが必要といった面倒さはありますが、たった数行のJavaScriptのコードでファイルアップロードが実装できるので、便利に使えそうです。
今回はストレージに対してパブリックアクセス可能としましたが、認証を行って、S3上のアクセス権限によってファイルに対する操作の可否を設定することもできます。

今回のコードはgoofmint/Monaca_AWS_Mobile_Hub_Demoにアップロードしてありますので実装時の参考にしてください。

Add User File Storage - AWS Mobile