Download files
Get
Get a presigned URL of a stored file. You can specify some options: mainly file access level
and whether to download
the file:
1await Storage.get(key: string, config: {2 level?: private | protected | public, // defaults to `public`3 identityId?: string, // id of another user, if `level: protected`4 download?: boolean, // defaults to false5 expires?: number, // validity of the URL, in seconds. defaults to 900 (15 minutes) and maxes at 3600 (1 hour)6 contentType?: string, // set return content type, eg "text/html"7 validateObjectExistence?: boolean, // defaults to false8 cacheControl?: string, // Specifies caching behavior along the request/reply chain9});
Storage.get
returns a signed URL string
to your file if download
is false, which is the default. You can use this to create a download link for users to click on. Note that this function does not check if the file exists by default. You can enable this check by setting validateObjectExistence
to true
.
Note: Currently, the expiration time of the presigned url is dependent on the session and will max out at 1 hour.
1// get the signed URL string2const signedURL = await Storage.get(key); // get key from Storage.list3
4// inside your template or JSX code. Note <a download> doesn't work here because it is not same origin5<a href={signedURL} target="_blank" rel="noreferrer">6 {fileName}7</a>;
Check for existence of a file
You can check for the existence of a file in the storage category's get
API using the validateObjectExistence
option. When this flag is enabled a get
call will return a pre-signed URL if the file exists and raise a 404
error if it does not. This allows you to check if an object exists during generating the presigned URL, which you can then use to download that object.
1// To check for existence of a file2await Storage.get('filename.txt', { validateObjectExistence: true });
If download
is true, Storage.get
returns an object with a Body
field of type Blob
. It is up to you to programmatically save it to disk (we suggest a method below) or do whatever else you need with it.
File download option
The download
option send you the object data for download or programmatic manipulation:
1const result = await Storage.get(`filename.txt`, { download: true });2
3// data.Body is a Blob4result.Body.text().then((string) => {5 // handle the String data return String6});
You can programmatically download Blobs using JavaScript:
1export function downloadBlob(blob, filename) {2 const url = URL.createObjectURL(blob);3 const a = document.createElement('a');4 a.href = url;5 a.download = filename || 'download';6 const clickHandler = () => {7 setTimeout(() => {8 URL.revokeObjectURL(url);9 a.removeEventListener('click', clickHandler);10 }, 150);11 };12 a.addEventListener('click', clickHandler, false);13 a.click();14 return a;15}16
17// usage18async function download() {19 const result = await Storage.get(fileKey, { download: true });20 downloadBlob(result.Body, 'filename');21}
The full return signature of Storage.get(key, { download: true })
looks like this:
1{2 $metadata: {3 attempts: 14 httpHeaders: {content-length: "388187", content-type: "audio/x-m4a", last-modified: "Fri, 09 Oct 2020 14:29:13 GMT", x-amz-id-2: "/rRqsX/c2h5V00tYMtDY994wEenyPm0SDw1lyWyncWepyg+T6YJJSjLHKIsz0dxMI3kN5KjA6GQ=", …}5 httpStatusCode: 2006 requestId: undefined7 totalRetryDelay: 08 },9 Body: Blob {size: 388187, type: "audio/x-m4a"}, // this will vary10 ContentLength: 388187,11 ContentType: "audio/x-m4a",12 ETag: ""c05e324f61613c2472d47a8ee6fbb628"",13 LastModified: Fri Oct 09 2020 22:29:13 GMT+0800 (Singapore Standard Time) {},14 Metadata: {},15 __type: "GetObjectOutput",16}
Monitor progress of download
To track the progress of your download, you can use progressCallback
:
1Storage.get('filename.txt', {2 download: true,3 progressCallback(progress) {4 console.log(`Downloaded: ${progress.loaded}/${progress.total}`);5 }6});
File Access Levels
You can choose to configure access level ahead of time, or at the point of calling Storage.get
:
1// Option 1: configure access ahead of time2Storage.configure({ level: 'private' });3const result = await Storage.get('welcome.png'); // Gets the welcome.png belonging to current user4
5// Option 2: configure access inside the call6const result = await Storage.get('welcome.png', { level: 'private' }); // same effect
Here is a quick guide to the access levels - see the docs for more detail:
public
: Accessible by all users of your app. Files are stored under thepublic/
path in your S3 bucket.protected
: Readable by all users, but writable only by the creating user. Files are stored underprotected/{user_identity_id}/
where theuser_identity_id
corresponds to the unique Amazon Cognito Identity ID for that user.
1// To get current user's objects2const result = await Storage.get('filename.txt', { level: 'protected' });3
4// To get other users' objects5const result = await Storage.get('filename.txt', {6 level: 'protected',7 identityId: 'xxxxxxx' // the identityId of that user8});
private
: Only accessible for the signed in user. Files are stored underprivate/{user_identity_id}/
where theuser_identity_id
corresponds to the unique Amazon Cognito Identity ID for that user.
Download expiry
You can use expires
option to limit the availability of your URLs. This configuration returns the pre-signed URL that expires in 60 seconds:
1await Storage.get('filename.txt', { expires: 60 });
Frequently Asked Questions
Users can run into unexpected issues, so we are giving you advance notice in documentation with links to open issues - please vote for what you need, to help the team prioritize.
Storage.get
is cached; if you have recently modified a file you may not get the latest version right away. You can pass incacheControl: 'no-cache'
to get the latest version.Storage.get
only returns the latest cached version of the file; there is not yet an API to view prior versions.- Image compression or CloudFront CDN caching for your S3 buckets is not yet possible.
- There is no API for Cognito Group-based access to files.
- There is currently no API for getting the identityId of other users; you have to retrieve this from elsewhere before calling
Storage.get
.