All Projects → dabit3 → basic-amplify-storage-example

dabit3 / basic-amplify-storage-example

Licence: other
A basic example app showing how to add storage with Amazon S3

Programming Languages

javascript
184084 projects - #8 most used programming language
HTML
75241 projects
CSS
56736 projects

Projects that are alternatives of or similar to basic-amplify-storage-example

Awesome Aws Amplify
Curated list of AWS Amplify Resources
Stars: ✭ 1,650 (+3337.5%)
Mutual labels:  amazon-s3, aws-amplify
amazon-cognito-example-for-external-idp
An example for using Amazon Cognito together with an external IdP
Stars: ✭ 222 (+362.5%)
Mutual labels:  aws-amplify
logstash-output-s3
No description or website provided.
Stars: ✭ 55 (+14.58%)
Mutual labels:  amazon-s3-storage
aws
Object Pascal implementation for Amazon S3
Stars: ✭ 67 (+39.58%)
Mutual labels:  amazon-s3-storage
BarsAppAmplify
React Native Bars App: AWS Amplify, AWS AppSync, AWS Cognito, Google Places, Mapbox
Stars: ✭ 29 (-39.58%)
Mutual labels:  aws-amplify
aws-amplify-cognito-authentication
👬 Fully functioning user authentication with AWS Amplify Cognito - Serverless | Angular ✅
Stars: ✭ 14 (-70.83%)
Mutual labels:  aws-amplify
aws-lab-guide
Amazon Web Services Practice Lab Guide. Absolute beginners can try this lab practice guide.
Stars: ✭ 25 (-47.92%)
Mutual labels:  amazon-s3-storage
clojurescript-amplified
Examples on how to setup a ClojureScript web app with tools from the JavaScript ecosystem.
Stars: ✭ 59 (+22.92%)
Mutual labels:  aws-amplify
react-chatbots
Building Chatbots with React, Amazon Lex, AWS Lambda, & AWS Amplify
Stars: ✭ 56 (+16.67%)
Mutual labels:  aws-amplify
data-transfer-hub
Seamless User Interface for replicating data into AWS.
Stars: ✭ 102 (+112.5%)
Mutual labels:  amazon-s3
graphql-ttl-transformer
♻ Enable DynamoDB's time-to-live feature to auto-delete old entries in your AWS Amplify API!
Stars: ✭ 75 (+56.25%)
Mutual labels:  aws-amplify
transilator
Text translation and synthesization Chrome plugin
Stars: ✭ 44 (-8.33%)
Mutual labels:  aws-amplify
OptimizeRasters
OptimizeRasters is a set of tools for converting raster data to optimized Tiled TIF or MRF files, moving data to cloud storage, and creating Raster Proxies.
Stars: ✭ 105 (+118.75%)
Mutual labels:  amazon-s3-storage
aws2openapi
Amazon Web Services API description to OpenAPI 3.0 definition
Stars: ✭ 45 (-6.25%)
Mutual labels:  amazon-s3-storage
aws-reinvent-2019-mobile-workshops
AWS re:Invent 2019 Mobile Workshops
Stars: ✭ 72 (+50%)
Mutual labels:  aws-amplify
client-side-databases
An implementation of the exact same app in Firestore, AWS Datastore, PouchDB, RxDB and WatermelonDB
Stars: ✭ 787 (+1539.58%)
Mutual labels:  aws-amplify
ecommerce-shopfront-on-aws
A high availability, API-first reference architecture for ecommerce using AWS services
Stars: ✭ 56 (+16.67%)
Mutual labels:  aws-amplify
cognito-amplify-custom-auth
A React/Redux web application that implements a custom UI for Cognito Userpool Auth using AWS Amplify
Stars: ✭ 27 (-43.75%)
Mutual labels:  aws-amplify
react-admin-amplify
AWS Amplify data provider for react-admin.
Stars: ✭ 130 (+170.83%)
Mutual labels:  aws-amplify
sandcastle
🏰 A Python script for AWS S3 bucket enumeration.
Stars: ✭ 53 (+10.42%)
Mutual labels:  amazon-s3

Basic Storage example with AWS Amplify

Storing & querying for files with AWS Amplify and React

The code in this app should be used for reference, but to recreate the app follow the below steps. You can also recreate this project by cloning it and running amplify init.

Getting started

Create a new React app:

$ npx create-react-app my-app

$ cd my-app

Install the Amplify libraries:

$ npm install aws-amplify aws-amplify-react

Initialize a new amplify app:

$ amplify init

Next, add auth:

$ amplify add auth

? Do you want to use the default authentication and security configuration? Default configuration
? How do you want users to be able to sign in? Username
? Do you want to configure advanced settings? No

Next, add storage with Amazon S3:

$ amplify add storage
? Please select from one of the below mentioned services: Content
? Please provide a friendly name for your resource that will be used to label this category in the project: <resource_name>
? Please provide bucket name: <unique_bucket_name>
? Who should have access: Auth and guest users
? What kind of access do you want for Authenticated users? create, update, read, delete
? What kind of access do you want for Guest users? create, update, read, delete
? Do you want to add a Lambda Trigger for your S3 Bucket? N

Configure the React app with Amplify

Open src/index.js and add the following three lines of code:

// src/index.js
import Amplify from 'aws-amplify'
import config from './aws-exports'
Amplify.configure(config)

Platform specific components

Photo Picker

import React from 'react';
import { Storage } from 'aws-amplify' 
import { PhotoPicker } from 'aws-amplify-react';

class App extends React.Component {
  state = {
    file: {}
  }
  onChange(data) {
    console.log('data: ', data)
    this.setState({ file: data.file })
  }

  saveFile = async () => {
    const { file } = this.state
    await Storage.put(file.name, file)
    console.log('successfully saved file...')
  }

  render() {
    return (
      <div>
        <PhotoPicker
          preview
          onPick={data => this.onChange(data)}
        />
        <button onClick={this.saveFile}>
          Save File
        </button>        
      </div>
    )
  }
}

export default App;

S3 Image

import React from 'react';
import { Storage } from 'aws-amplify' 
import { S3Image } from 'aws-amplify-react';

class App extends React.Component {
  state = {
    files: [],
  }
  
  async componentDidMount() {
    const files = await Storage.list('')
    console.log('files: ', files)
    this.setState({ files })
  }

  render() {
    return (
      <div>
        {
          this.state.files.map((f, i) => (
            <div style={{ width: 400, margin: '0 auto' }} key={i}>
              <S3Image
                imgKey={f.key}
              />
            </div>
          ))
        }        
      </div>
    )
  }
}

export default App;

Photo Album

import React from 'react';
import { S3Album } from 'aws-amplify-react';

class App extends React.Component {
  render() {
    return (
      <div>
        <S3Album path='' />    
      </div>
    )
  }
}

export default App;

Manually working with the Storage API - storing an image

// src/App.js
import React from 'react';
import { Storage } from 'aws-amplify' 

class App extends React.Component {
  onChange(e) {
    const file = e.target.files[0];
    Storage.put(file.name, file)
    .then (result => console.log(result))
    .catch(err => console.log(err));
  }

  render() {
    return (
      <input
        type="file" accept='image/png'
        onChange={(e) => this.onChange(e)}
      />
    )
  }
}

export default App;

Viewing a single file or image from a folder or array of images

import React from 'react';
import { Storage } from 'aws-amplify' 

class App extends React.Component {
  state = {
    files: [],
    file: ""
  }
  componentDidMount() {
    this.listFiles()
  }
  onChange(e) {
    const file = e.target.files[0]
    Storage.put(file.name, file)
    .then (() => this.listFiles())
    .catch(err => console.log(err));
  }

  listFiles = async () => {
    const files = await Storage.list('')
    this.setState({ files })
  }

  selectFile = async file => {
    const signed = await Storage.get(file.key)
    this.setState({ file: signed })
  }

  render() {
    return (
      <div>
        <input
          type="file" accept='image/png'
          onChange={(e) => this.onChange(e)}
        />
        <button onClick={this.listFiles}>
          List Files
        </button>
        <div>
        {
          this.state.files.map((file, i) => (
           <p onClick={() => this.selectFile(file)}>{file.key}</p>
          ))
        }
        </div>
        {
          this.state.file && (
            <img
              src={this.state.file}
              style={{width: 300}}
            />
          )
        }
      </div>
    )
  }
}

export default App;

Viewing a list of images after storing them

import React from 'react';
import { Storage } from 'aws-amplify' 

class App extends React.Component {
  state = {
    files: []
  }
  onChange(e) {
    const file = e.target.files[0]
    Storage.put(file.name, file)
    .then (() => this.listFiles())
    .catch(err => console.log(err));
  }

  listFiles = async () => {
    const files = await Storage.list('')
    let signedFiles = files.map(f => Storage.get(f.key))
    signedFiles = await Promise.all(signedFiles)
    console.log('signedFiles: ', signedFiles)
    this.setState({ files: signedFiles })
  }

  render() {
    return (
      <div>
        <input
          type="file" accept='image/png'
          onChange={(e) => this.onChange(e)}
        />
        <button onClick={this.listFiles}>
          List Files
        </button>
        <div>
        {
          this.state.files.map((file, i) => (
            <img
              key={i}
              src={file}
              style={{height: 300}}
            />
          ))
        }
        </div>
      </div>
    )
  }
}

export default App;

Lambda Trigger for resizing images

Let's add a new Lambda function that will resize an image whenever we upload one to S3 to create thumbnails.

$ amplify update storage
? Please select from one of the below mentioned services: Content
? Who should have access: Auth & Guest users
? What kind of access do you want for Authenticated users? keep existing settings
? What kind of access do you want for Guest users? keep existing settings
? Do you want to add a Lambda Trigger for your S3 Bucket? Y
? Select from the following options: Create a new function
? Do you want to edit the local S3Triggerf985d3b6 lambda function now? Y

Let's update the function to resize images. Update this file with the following code:

//  amplify/backend/function/<function_name>/src/index.js.
const sharp = require('sharp')
const aws = require('aws-sdk')
const s3 = new aws.S3()

const WIDTH = 100
const HEIGHT = 100

exports.handler = async (event, context) => {
  const BUCKET = event.Records[0].s3.bucket.name

  // Get the image data we will use from the first record in the event object
  const KEY = event.Records[0].s3.object.key
  const PARTS = KEY.split('/')

  // Check to see if the base folder is already set to thumbnails, if it is we return so we do not have a recursive call.
  const BASE_FOLDER = PARTS[0]
  if (BASE_FOLDER === 'thumbnails') return

  // Stores the main file name in a variable
  let FILE = PARTS[PARTS.length - 1]

  try {
    const image = await s3.getObject({ Bucket: BUCKET, Key: KEY }).promise()

    const resizedImg = await sharp(image.Body).resize(WIDTH, HEIGHT).toBuffer()

    await s3.putObject({ Bucket: BUCKET, Body: resizedImg, Key: `thumbnails/thumbnail-${FILE}` }).promise()

    return
  }
  catch(err) {
    context.fail(`Error resizing files: ${err}`);
  }
}

Next, we need to make sure that the sharp library is installed. To do so, you can add a dependency in the package.json of the function.

amplify/backend/function/<function_name>/src/package.json

"scripts": {
  "install": "npm install --arch=x64 --platform=linux --target=10.15.0 sharp"
},
"dependencies": {
  "sharp": "^0.23.2"
}

Finally, for sharp to work, we need to update the Node.js runtime to be 10.x. To do so, open /amplify/backend/function/S3Triggerf985d3b6/-cloudformation-template.json and update the Runtime key:

"Runtime": "nodejs10.x",

Now, to deploy the updated function, run the push command:

$ amplify push
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].