After I described my expirience with AWS Amplify GraphQL APIs here I'd like to describe how I use AWS Amplify storage
AWS Amplify add storage
First I added the new storage category for images like it is decribed in the documentation.
https://docs.amplify.aws/lib/storage/getting-started?platform=js
Two command are enough for the initial setup
amplify add storage
amplify push
Usage in React
In my user profile page I had to add Storage to the imports. The configuration was already available through the categories Authentication and Analytcis.
import Amplify, { Analytics, Auth, Storage } from "aws-amplify";
import awsconfig from "./../../aws-exports";
Amplify.configure(awsconfig);
The specific Storage configuration was one-liner. Because every user should have his own picture the access level is "private".
Storage.configure({ track: true, level: "private" });
Combination with Pinpoint 📈
In the storage configuration, track: true
automatically enabled tracking of file operations in Pinpoint. Prerequisite is the category Analytics.
https://docs.amplify.aws/lib/storage/autotrack?platform=js
Upload picture
To upload a picture I use this components. The img component open the file dialog and the input component upload the file.
<a href="#">
<input
type="file"
onChange={onProcessFile}
ref={fileInput}
hidden={true}
/>
</a>
<img src={image} onClick={onOpenFileDialog} />
The variable fileInput
"connecting" the file dialog with the upload function.
let fileInput = React.createRef();
const onOpenFileDialog = () => {
fileInput.current.click();
};
const onProcessFile = e => {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
try {
reader.readAsDataURL(file);
} catch (err) {
console.log(err);
}
reader.onloadend = () => {
setImage(reader.result);
};
Storage.put("profilePicture.png", file, {
contentType: "image/png"
})
.then(result => console.log(result))
.catch(err => console.log(err));
};
After a picture is choosed via Storage.put
the file will be uploaded to S3.
With the the state image the picture is "transferred". Avatar is the placeholder if no profile picture was choosed.
const [image, setImage] = useState(avatar);
Download picture
The profile picture will be downloaded every time the user profile page is called. With Storage.get
there will always returned a signed url. Therefore the status must be checked if the image is available at all. That's discussed here: https://github.com/aws-amplify/amplify-js/issues/1145
useEffect(() => {
onPageRendered();
}, []);
const onPageRendered = async () => {
getProfilePicture();
};
const getProfilePicture = () => {
Storage.get("profilePicture.png")
.then(url => {
var myRequest = new Request(url);
fetch(myRequest).then(function(response) {
if (response.status === 200) {
setImage(url);
}
});
})
.catch(err => console.log(err));
};
Coding
JohannesKonings / fff-badminton
An AWS Amplify Webapp for tracking badminton games based on the Creative Tim Template Material Dashboard React
fff-badminton
Template
Documentation
The documentation for the Material Dashboard React is hosted at our website.
Technical description of the webapp
https://dev.to/johanneskonings/series/5661
development
https://aws.amazon.com/de/amplify/
data model
local dev
amplify mock
test
npx cypress open
npm run cypress:open
semantic release
GITHUB_TOKEN=<<GitHub token>> npx semantic-release --dry-run
Top comments (7)
Isn't
Storage.get("profilePicture.png")
just generic? So any other user logging in will pull this same storage item?What is the method for making this unique to the authenticated user?
I would assume something like the following:
Also, there maybe some issues with the
.configure({ level: "private" });
I have seen some 403 permission denied which is discussed here GitHub Issue: Amplify S3 404Hi, it's unique through the level "private" via this command
Storage.configure({ track: true, level: "private" });
docs.amplify.aws/lib/storage/confi...
So far I had no 403 permission denied.
what about when we need to display this avatar image to other users of the app?
Hopefully, I found some time the next days to create an example.
Presumably, this must then be stored differently.
Hi Johannes! Can you make a post detailing how you would do this with react native?
I would like to, unfortunately, I'm not very experienced in react native.