LoginSignup
2
0

Amplify Gen2のStorage機能を使ってみた-②アップロードとリスト-

Last updated at Posted at 2024-06-03

どうも、駆け出し12冠エンジニアのアスカです。Amplify Gen2がGAしてドキュメントのStorage機能に関する部分が充実していたので、それを参考にしながら触ってみます!
Amplify Gen2のドキュメント

想像以上にボリュームがあるので、連載の形をとっています。今回はアップロードとダウンロードの機能を触っていきたいと思います。
参考:
Amplify Gen2のStorage機能を使ってみた-①最初のアップロードまで-

アップロード

Storage Manager React UI Componentを使う

まず以下のコマンドでライブラリをインポートします。

Terminal
npm add @aws-amplify/ui-react-storage aws-amplify

早速Reactを書いて実装してみます。
アップロードボタンのコンポーネントを作成します。

src/components/Element/uploadbutton.tsx
import { StorageManager } from '@aws-amplify/ui-react-storage';
import '@aws-amplify/ui-react/styles.css';

export const DefaultStorageManagerExample = () => {
  return (
    <StorageManager
      acceptedFileTypes={['image/*']}
      path="public/"
      maxFileCount={1}
      isResumable
    />
  );
};

このボタンをメイン部分にインポートします。

src/App.tsx
import { Authenticator } from '@aws-amplify/ui-react'
import '@aws-amplify/ui-react/styles.css'
import {DefaultStorageManagerExample } from '../src/components/Elements/Buttons/uploadbutton';

function App() {

  return (
    <Authenticator>
      {({ signOut, user }) => (
    <main>
      <h1> Welcome to {user?.signInDetails?.loginId}</h1>
      <button onClick={signOut}>Sign out</button>
      <DefaultStorageManagerExample/>
    </main>       
    )}
    </Authenticator>
  );
}

export default App;

これでボタンは生成されますが、ストレージのパスに許可を与えないとアップロードに失敗します。
ここでは以下のようにamplify/storage/resource.tsを編集します。

amplify/storage/resource.ts
import { defineStorage } from '@aws-amplify/backend';

export const storage = defineStorage({
  name: 'amplifygen2Test',
  access: (allow) => ({
    'public/*': [
      allow.authenticated.to(['read','write']),
      allow.guest.to(['read'])
    ],
  })
});

これでストレージ配下のpublic/にログイン済みのユーザがファイルをアップロード出来るようになりました。

カスタムは色々可能で、詳細は下記ドキュメントにあります。
Amplify Dev Center
多くのPropsが用意されていてカスタマイズ性が高そうです。
例えば、processFile?にファイルを処理する関数を入れると、アップロード時に処理が走ります。
displayText Propsを使えばUIの表示文字の変更も可能ですし、各種オーバーライドも可能でデザインも自由度高く変更出来そうです。今回は表示文字を日本語に変えてみます。

src/components/Element/uploadbutton.tsx
import { StorageManager } from '@aws-amplify/ui-react-storage';
import '@aws-amplify/ui-react/styles.css';

export const DefaultStorageManagerExample = () => {
  return (
    <StorageManager
      acceptedFileTypes={['image/*']}
      path="public/"
      maxFileCount={1}
      isResumable
+     displayText={{
+       // some text are plain strings
+        dropFilesText: 'ドラッグ&ドロップ',
+        browseFilesText: 'ファイルを選択する',
+        uploadSuccessfulText: 'アップロード完了',
+        // others are functions that take an argument
+        getFilesUploadedText(count) {
+          return `${count}枚 画像がアップロードされました`;
+        },
+      }}
    />
  );
};

簡単に表示を日本語にする事が出来ました。
画像
要件に応じてまだまだ出来る事はあるので、これからも利用していきたいです。

リスト

ドキュメントにはlist関数の使用方法が記載されています。これを利用して簡単なリストコンポーネントを実装してみます。

src/components/Lists/list.tsx
import React, { useState, useEffect } from 'react';
import { list } from 'aws-amplify/storage';

const FileList = () => {
  const [files, setFiles] = useState([]);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchFiles = async () => {
      try {
        const result = await list({
          path: 'public/'
        });
        setFiles(result.items); 
      } catch (err) {
        console.error(err);
        setError(err.message);
      }
    };

    fetchFiles();
  }, []);

  return (
    <div>
      <h1>File List</h1>
      {error && <p>Error fetching files: {error}</p>}
      <ul>
        {files.map((file, index) => (
          <li key={index}>
            {file.path} - Last modified: {new Date(file.lastModified).toLocaleString()}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default FileList;

fetchFiles 関数でS3内のpublic/配下のファイルリストを取得してこれを並べて表示します。ここではpathと最終編集日時を表示していますが、それ以外にもsizeやnextTokenといったプロパティがあります。
上記のコードで定義したFileListをApp.tsxに実装してみます。

src/App.tsx

import { Authenticator } from '@aws-amplify/ui-react'
import '@aws-amplify/ui-react/styles.css'
import { useEffect, useState } from "react";
import type { Schema } from "../amplify/data/resource";
import { generateClient } from "aws-amplify/data";
import { uploadData } from 'aws-amplify/storage';
import {DefaultStorageManagerExample } from '../src/components/Elements/Buttons/uploadbutton';
+ import FileList from '../src/components/Elements/Lists/list_test'


const client = generateClient<Schema>();

function App() {


  const [todos, setTodos] = useState<Array<Schema["Todo"]["type"]>>([]);

  useEffect(() => {
  const [file, setFile] = useState<File | undefined>();

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const files = event.target.files;
    if (files) {
      setFile(files[0]);
    }
  };

  const handleUpload = () => {
    if (file) { // file が undefined でないことを確認
      uploadData({
        path: `picture-submissions/${file.name}`,
        data: file,
      })
      alert(`${file.name}がアップロードされました。`)
  } else{
    alert(`ファイルが選択されていません。`)
  }; 
};

  return (
    <Authenticator>
      {({ signOut, user }) => (
    <main>
      <h1> Welcome to {user?.signInDetails?.loginId}</h1>
    
      <button onClick={signOut}>Sign out</button>
      
      <DefaultStorageManagerExample/>  
+     <FileList/>
    </main>       
    )}
    </Authenticator>
  );
}

export default App;

public/にアップロードしたファイルパスをリストする事が出来ました。
画像
これで画像の表示やダウンロードに繋げる事が出来ます。

まとめ

この記事ではドキュメントをベースに画像のアップロードとリストを実装してみました。
リストに関してはドキュメント上にsampleのコンポーネントは無かったので、この記事が少しでも初心者仲間のが参考になれば嬉しいです。次はダウンロードや削除機能を試していきます。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0