AWS Amplify Storage module gives a simple mechanism for managing user content in public or private storage.
- Installation and Configuration
- Amazon S3 Bucket CORS Policy
- Access Level
- Call APIs
- React Development
Please refer to this Guide for general setup. Here are Analytics specific setup.
The default implementation of the Storage module leverages Amazon S3.
import Amplify from 'aws-amplify';
Amplify.configure(
Auth: {
identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab', //REQUIRED - Amazon Cognito Identity Pool ID
region: 'XX-XXXX-X', // REQUIRED - Amazon Cognito Region
userPoolId: 'XX-XXXX-X_abcd1234', //OPTIONAL - Amazon Cognito User Pool ID
userPoolWebClientId: 'XX-XXXX-X_abcd1234', //OPTIONAL - Amazon Cognito Web Client ID
},
Storage: {
bucket: '', //REQUIRED - Amazon S3 bucket
region: 'XX-XXXX-X', //OPTIONAL - Amazon service region
});
To create a project fully functioning with the Storage category.
$ npm install -g awsmobile-cli
$ cd my-app
$ awsmobile init
$ awsmobile enable user-files
In your project i.e. App.js:
import Amplify, { Storage } from 'aws-amplify';
import aws_exports from './aws-exports';
Amplify.configure(aws_exports);
To make calls to your S3 bucket from your App, make sure CORS is turned on:
- Go to AWS S3 Console and click on your project's userfiles bucket.
- Click on the Permissions tab for your bucket, and then click on CORS configuration tile.
- Update your bucket's CORS Policy to look like:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<ExposeHeader>x-amz-server-side-encryption</ExposeHeader>
<ExposeHeader>x-amz-request-id</ExposeHeader>
<ExposeHeader>x-amz-id-2</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Note: You can restrict the access to your bucket by updating AllowedOrigin to be more domain specific.
Storage has two access levels: public
and private
.
Files with public access level can be accessed by all users who are using the app. In S3, they are stored under the public/
path in your S3 bucket.
Files with private access level are only accessible by the specific authenticated user alone. In S3, they are stored under private/{user_identity_id}/
where the ID corresponds to a unique Amazon Cognito Identity ID, generated for that user.
The access level can be configured on the Storage object globally. Alternatively it can be set on an individual function call. By default the access level is public
.
Configuration on the Storage object
Storage.configure({ level: 'private' });
Storage.get('welcome.png'); // Gets the welcome.png belongs to current user
Configuration when calling the API
Storage.get('welcome.png', { level: 'public' }); // Gets welcome.png in public space
The default access level is public
:
Storage.get('welcome.png'); // Get welcome.png in public space
There is also a shortcut vault
, which is merely a Storage instance with private
level set:
Storage.vault.get('welcome.png'); // Get the welcome.png belonging to current user
You can enable automatic tracking of events by setting track
to true
when calling the API. (Note: this option is currently only supported in aws-amplify). Enabling this will automatically send 'Storage' events to Amazon Pinpoint and you will be able to see them within the AWS Pinpoint console under Custom Events. The event name will be 'Storage' and within the attributes will be details about the operations that occurred. For example Storage -> method -> put etc.
For example:
Track all the storage apis:
Storage.configure({ track: true })
Track specified storage api:
Storage.get('welcome.png', { track: true });
You can also use the track property directly on React components.
Import Storage from the aws-amplify library:
import { Storage } from 'aws-amplify';
If use aws-exports.js
file, Storage is already configured. To configure Storage separately,
Storage.configure({
bucket: //Your bucket ARN;
region: //Specify the region your bucket was created in;
identityPoolId: //Specify your identityPoolId for Auth and Unauth access to your bucket;
});
Put data into Amazon S3.
Public
Storage.put('test.txt', 'Hello')
.then (result => console.log(result))
.catch(err => console.log(err));
Private
Storage.put('test.txt', 'Private Content', {
level: 'private',
contentType: 'text/plain'
})
.then (result => console.log(result))
.catch(err => console.log(err));
Get a public accessible URL for data stored.
Public
Storage.get('test.txt')
.then(result => console.log(result))
.catch(err => console.log(err));
Private
Storage.get('test.txt', {level: 'private'})
.then(result => console.log(result))
.catch(err => console.log(err));
Delete data stored with key specified.
Public
Storage.remove('test.txt')
.then(result => console.log(result))
.catch(err => console.log(err));
Private
Storage.remove('test.txt', {level: 'private'})
.then(result => console.log(result))
.catch(err => console.log(err));
List keys under path specified.
Public
Storage.list('photos/')
.then(result => console.log(result))
.catch(err => console.log(err));
Private
Storage.list('photos/', {level: 'private'})
.then(result => console.log(result))
.catch(err => console.log(err));
aws-amplify-react
package provides the following components:
Picker
is used to pick file from local device. PhotoPicker
and TextPicker
are specific to photo and text file picking.
Listen to PhotoPicker
onPick event:
import { PhotoPicker } from 'aws-amplify-react';
render() {
<PhotoPicker onPick={data => console.log(data)}/>
}
To have a preview
<PhotoPicker preview onLoad={dataURL => console.log(dataURL)} />
onLoad
gives dataURL of the image. With that, you may not need the built-in preview. Then just hide it
<PhotoPicker preview="hidden" onLoad={dataURL => console.log(dataURL)} />
S3Image
component renders Amazon S3 key as an image:
import { S3Image } from 'aws-amplify-react';
render() {
return <S3Image imgKey={key} />
}
For private image, supply the level
property:
return <S3Image level="private" imgKey={key} />
To upload, set the body property to S3Image:
import { S3Image } from 'aws-amplify-react';
render() {
return <S3Image imgKey={key} body={this.state.image_body} />
}
To hide the image shown in the S3Image, set hidden
import { S3Image } from 'aws-amplify-react';
render() {
return <S3Image hidden imgKey={key} />
}
Image URL
S3Image
converts path to actual URL. To get the URL, listen to the onLoad
event:
<S3Imag imgKey={key} onLoad={url => console.log(url)}
Photo Picker
Set picker
property to true on S3Image
. A PhotoPicker
let user pick photos on his/her device.
<S3Image imgKey={key} picker />
After pick, the image will be uploaded to imgKey
. You may just provide path
, path plus image file name will be the upload key.
<S3Image path={path} picker />
To have custom key you can provide a callback:
function fileToKey(data) {
const { name, size, type } = data;
return 'test_' + name;
}
...
<S3Image path={path} picker fileToKey={fileToKey}/>
S3Image
will escape all spaces in key to underscore. For example, 'a b' becomes 'a_b'.
S3Text
has similar behaviors as S3Image
, only this is for text contents.
S3Album
holds a list of S3Image
and S3Text
objects:
import { S3Album } from 'aws-amplify-react';
render() {
return <S3Album path={path} />
For private album, supply the level
property:
return <S3Album level="private" path={path} />
You might have files under the path not in album. In this case you can provide a filter
prop:
return <S3Album
level="private"
path={path}
filter={(item) => /jpg/i.test(item.path)}
/>
Picker
Set picker
property to true on S3Album
. A Picker
let user pick photos or text files on his/her device.
<S3Album path={path} picker />
By default photo picker saves photo on S3 with filename as key. To have custom key you can provide a callback:
function fileToKey(data) {
const { name, size, type } = data;
return 'test_' + name;
}
...
<S3Album path={path} picker fileToKey={fileToKey}/>
S3Album
will escape all spaces in key to underscore. For example, 'a b' becomes 'a_b'.
You can automatically track Storage
operations on the following React components: S3Album
, S3Text
, S3Image
by providing a track
prop:
return <S3Album track/>
Enabling this will automatically send 'Storage' events to Amazon Pinpoint and you will be able to see them within the AWS Pinpoint console under Custom Events. The event name will be 'Storage' and within the attributes will be details about the operations that occurred. For example Storage -> method -> put etc.