Uploading image files to AmazonS3 using ReactJs - reactjs

I am fairly new to web development (currently enrolled in a bootcamp) and have struggled finding the needed resources to incorporate uploading to Amazon S3 in my project. I apologize for the vagueness ahead of time.
I currently have a react app that is pulling images from my AmazonS3 account but I am intending to give the user the ability to upload to my bucket and use/view the images on my website.
I have tried watching tutorials and looking at various GitHub Repo's to identify what I am missing but have been unable to locate a tutorial that involves React, JSX and Javascript. (I've seen jquery, PHP, etc). Ultimately, I know this task is difficult and I am willing to put in the work but felt the need to ask if anyone knows of a useful resource that can help me?
I've tried using the 'aws-nodejs-sample' repo, 'themetoerchef/uploading-with-react' repo, watched a youTube tutorial, I've looked into FineUploader and have read the react-S3-uploader npm files but am unable to connect the dots. Additionally, I've included my AWS access keys in my .env file and tried making query strings to access the S3 bucket.
Is there a better way to go about this or are there other ways to upload with react that may be useful outside of S3?

To upload to s3 from the browser you need to get a signedUrl from an aws sdk which is how aws verifies your identity. In my last application I used skd for nodejs to generate the signedUrl and pass it to my front end application to use in pushing files to s3. You don't have to go that route there is an sdk that can be used by javascript within the browser.
Check this aws link for more

Go to your project directory and run
npm install --save react-aws-s3
https://www.npmjs.com/package/react-aws-s3
And add the code in your component as per the NPM document
import S3 from 'react-aws-s3';
const config = {
bucketName: 'myBucket',
dirName: 'media', /* optional */
region: 'eu-west-1',
accessKeyId: 'JAJHAFJFHJDFJSDHFSDHFJKDSF',
secretAccessKey: 'jhsdf99845fd98qwed42ebdyeqwd-3r98f373f=qwrq3rfr3rf',
s3Url: 'https:/your-custom-s3-url.com/', /* optional */
}
const ReactS3Client = new S3(config);
/* Notice that if you don't provide a dirName, the file will be automatically uploaded to the root of your bucket */
/* This is optional */
const newFileName = 'test-file';
ReactS3Client
.uploadFile(file, newFileName)
.then(data => console.log(data))
.catch(err => console.error(err))
/**
* {
* Response: {
* bucket: "myBucket",
* key: "image/test-image.jpg",
* location: "https://myBucket.s3.amazonaws.com/media/test-file.jpg"
* }
* }
*/
});
Now its everything is done, make sure to load your keys and secrets from Process ENV.
NOTE: Please don't forget to add the CORS policy on the AWS bucket if you see corse error, see here the detailed example.
thanks

Related

.NET / React App not serving /.well-known/filename

I'm trying to setup Apple Pay via Stripe, which requests access to a file to verify domain ownership. The problem I'm having is that this file has no extension, so either React, Azure or my .NET application does not like it!
I've tried various solutions to date within the web.config but to no avail.
The file in question is: /.well-known/apple-developer-merchantid-domain-association
My project is a .NET project running a React SPA. I've added the file mentioned above to the /public folder, too.
I can access .txt files in the same folder, so the path/folder is accessible - It seems to be a problem with the lack of extension.
I've managed to resolve this with the following, and ensuring the ./well-known and subfiles are in my project root.
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, #".well-known")),
RequestPath = new PathString("/.well-known"),
DefaultContentType = "application/json",
ServeUnknownFileTypes = true
});

NextJs: The Serverless Function exceeds the maximum size limit of 50mb

I'm new working with NextJs and when trying to deploy my project to Vercel I'm getting the following error:
Error! The Serverless Function "api/auth" is 50.55mb which exceeds the maximum size limit of 50mb.
I have spent a lot of my time trying to find a proper answer but I didn't find any. Here is the code of the api request I'm making:
const { auth: adminAuth } = require("firebase/admin");
export default async function auth(req, res) {
const tokenId = req.query.token;
return new Promise((resolve) => {
adminAuth
.verifyIdToken(tokenId)
.then((user) => {
res.json(user);
resolve();
})
.catch(() => {
res.status(302).send("Invalid authentication");
resolve();
});
});
}
I'll be really grateful if anybody can help me, thanks y'all!
I've been dealing with the same issue. It appears that when bundling the serverless function vercel is pulling in ALL assets within your project. So 50.55MB is likely the size of your current entire build. I'm researching how to only include certain files within the vercel.json but have so far not figured exactly how to do that. For now you could probably just remove a few files from your public assets to get under the limit.
This is likely caused by firebase/admin including everything in the firebase package, not just the "admin" parts.
You can verify this by creating a file with only the import and running #vercel/nft to trace the files.
npm init -y
npm add firebase
echo "const { auth: adminAuth } = require('firebase/admin')" > index.js
npm i -g #vercel/nft
nft print index.js
The entire firebase package is quite large, so its best to follow the recommendation from the firebase team and use the firebase-admin package inside Serverless Functions.
This SDK (firebase) is intended for end-user client access from environments such as the Web, mobile Web (e.g. React Native, Ionic), Node.js desktop (e.g. Electron), or IoT devices running Node.js. If you are instead interested in using a Node.js SDK which grants you admin access from a privileged environment (like a server), you should use the Firebase Admin Node.js SDK (firebase-admin).
source: firebase NPM
You could add .vercelignore file to avoid this
Ref: https://vercel.com/guides/prevent-uploading-sourcepaths-with-vercelignore
# Ignore everything (folders and files) on root only
/*
!api
!vercel.json
!*.html
!*.css

Removing the need for pathing in cloudFront distribution of S3 bucket requiring .html at the end of the page name, in Next.js project

I have a Next.js, React, Ts project that exists on a S3 bucket as a static site and is distributed via cloudFront.
The problem I'm running into is for me to go a different page I have to append .html at the end of the page name.
So mysite.com/profile will return a <Code>NoSuchKey</Code> error, however mysite.com/profile.html will route me correctly.
Is there some way to remove this necessity?
If this is a next issue i'm using
npx next build
npx next export
To build and export the /out directory which I then upload to my S3 bucket
my next.config.js
module.exports = {
target: "serverless"
}
I had it like this as I was originally making use of serverless for Next but have since moved away from it as I'm largely making use of client-side rendering and don't need any of the features it was providing and I am still in the process of doing a cleanup on the project.
Routing in S3 is done with exact match of the file name. You can remove .html extension to use routing as you like. And set metadata Content-type to text/html, to view it properly in browser

Stage management with AWS Mobile hub and AWS Amplify

I am currently writing a web app and am using AWS Amplify.
I created my API Gateway and my lambdas before using Amplify so I imported my existing API to Mobile Hub.
My API gateway has 2 stages dev and prod.
According to the Amplify documentation here is the code to call my API from my app.
API.get(apiName, path, myInit).then(response => {
// Add your code here
}).catch(error => {
console.log(error.response)
});
apiName is auto generated by Mobile Hub and is always ...amazonaws.com/dev
path will be /items for example
resulting in a call being made to ...amazonaws.com/dev/items
I haven't seen anything in Amplify or AWS documentation to be able to call ...amazonaws.com/prod/items using the Amplify library.
I tried to edit the mobile-hub-project.yml and change it from :
features:
cloudlogic: !com.amazonaws.mobilehub.v0.CloudLogic
components:
apiName: !com.amazonaws.mobilehub.v0.API
attributes:
...
sdk-generation-stage-name: dev
to :
features:
cloudlogic: !com.amazonaws.mobilehub.v0.CloudLogic
components:
apiName: !com.amazonaws.mobilehub.v0.API
attributes:
...
sdk-generation-stage-name: prod
and push the new configuration but the behaviour is still the same.
Could anyone help me to manage multiple stages using Amplify ?
can you check the file aws-exports.js on aws_cloud_logic_custom array. there each endpoint has an attribute called name which is the one you use with the Amplify. You can edit the endpoint by changing to the stage you want to use. By default aws-exportsuses dev stage.

how can I enable the user download the whole application from the client side?

So, I have a web app hosted in heroku which is automatically updated when I update my github repository. I want to enable the user to download the all the app files with their folders, images etc as a zip from the client side so he can run it offline locally. I also want to add a file with user's comments to that zip before I force it to be downloaded on his browser.
I found a way to do it by redirecting him to github (but this will actually not redirect him there, it will just force a zip from github to be downloaded) :
window.location.replace("https://github.com/foo/FOO/archive/master.zip");
But this solution doesn't work for me because I want to add to that zip an other file which will be created at the moment of the user download request.
Does anyone have a solution to this?
Is there a way to do that by making requests to herokku to receive the files and using the jszip to pack them?
I found the solution using github's service, JSZipUtils and jszip. Here's the code for whom it might of help :
var content = null;
JSZipUtils.getBinaryContent("https://github.com/foo/FOO/archive/master.zip", function(err, data) {
if(err) {
throw err; // or handle err
}
var zip = new JSZip(data);
// to remove a not needed file
zip.remove("CWAPP-master/abc.js");
// to add a custom file
zip.file('CWAPP-master/myClientSideFile.js',file);
content = zip.generate({type:"blob"});
saveAs(content, 'myZip'); // force download
});

Resources