So I am going to be making a very, very, very simple photo cloud storage using Firebase's Storage. Everything is going as planned except when I upload an image through HTML to send to the backend, it just sends something similar like this:
And that's the missing image icon! So here is my code for the file upload:
<!--HTML code, inside of a public folder-->
<form enctype="multipart/form-data" method="POST" action="/submit-form">
<input name="file" type="file" accept="image/png" />
<input type="submit" value="submit" />
</form>
//The code which sends the image to firebase's Storage
var bucket = admin.storage().bucket();
app.post('/submit-form', (req, res) => {
var imageChosen = `${req.body.file}`; //I know it's useless to add the `${}` but I just do it, ok!
fs.writeFile('sentImage.png', imageChosen, function (err) {
if (err) throw err;
console.log('Saved!');
});
bucket.upload('sentImage.png');
res.end('Image sent!')
});
So why is it only sending the missing image icon?
The point
If you don't want the detailed explanation, here is a summary below:
I am sending an image through an HTML form inside of a public folder, then it saves it to a local file and uploads it to Firebase's Storage, except that it's sending the missing image icon instead of the image uploaded through the HTML form.
How the cloud storage works
So basically you upload an image, then HTML sends the file to the backend. After that the backend uses the fs module to save it to a local file for Firebase to upload it to it's Storage
Related
I am working on a music app,how can i upload audio file in my expressjs using cloudinary or any other way?
I tried using thesame format for image upload but didnt work
enter image description here
To upload audio using Express JS, you will need to use the multer middleware. Here is an example of how you can set up the multer middleware and use it to handle audio file uploads:
First, install the multer package:
npm install multer
Next, require the multer package in your Express app:
const multer = require('multer')
Set up the multer middleware by specifying where you want the uploaded audio files to be stored. For example:
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/audio/')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
Use the multer middleware in your route handling function to handle the audio file upload. For example:
app.post('/upload-audio', multer({ storage }).single('audio'), (req, res) => {
// req.file contains the uploaded audio file
// Do something with the audio file, such as save it to a database or storage service
res.send('Audio file successfully uploaded!')
})
In your HTML form for uploading audio, make sure to include the enctype="multipart/form-data" attribute and specify the name of the file input as audio. For example:
<form action="/upload-audio" method="post" enctype="multipart/form-data">
<input type="file" name="audio" accept="audio/*">
<button type="submit">Upload Audio</button>
</form>
I hope this helps!
To add to Jack's answer, there is a Cloudinary storage engine for Multer you can use to send your files to Cloudinary rather than keeping the assets on disk.
https://www.npmjs.com/package/multer-storage-cloudinary
When initializing the CloudinaryStorage object you can pass parameters to Cloudinary, including the resource_type. If you set that to auto (default is image if none is provided) then Cloudinary assigns the appropriate resource_type once it processes the upload request. For audio files, it will assign resource_type: "video" because audio files fall under this and for images, it'll assign "image". If you were to upload text files and you used resource_type: "auto" in your request, then Cloudinary will assign "raw" as the resource_type.
You will just need to store (e.g. in your database) the resource_type, type and public_id fields returned in the response to a successful upload and you can then refer to any of your files on Cloudinary.
The reason you want to save the 'resource_type' and 'type' and not only the 'public_id' is because, in Cloudinary, an asset is only unique if in combination with the 'resource_type' and 'type'. E.g. the below assets with the same public_id (sample) are different entities because of a different 'resource_type' and/or 'type':
image/upload/sample
image/private/sample
video/upload/sample
video/authenticated/sample
References:
https://cloudinary.com/documentation/upload_images#asset_types
I am making a nodejs app which displays pictures stored on servers ,I was using multer to store pictures in the same directory and I was using mongodb as my database to store the path of the picture that user uploads , and then i read the path and displayed the pictures something like this,
<div class="post-image flex">
<%var imagesource='../'+postobj.blob.path%>
<div>
<img class='onbottomimage' src="<%=imagesource%>" >
</div>
</div>
everything was working fine locally.
but now I have deployed my app to heroku and found out I cannot store pictures on heroku as the user uploads them, I still have the pictures stored in mongodb in base 64 format something like this
image
:
Binary('/9j/4AAQSkZJRgABAgEAYABgAAD/7gAOQWRvYmUAZAAAAAAB/+EUI0V4aWYAAE1NACoAAAAIAAcBMgACAAAAFAAAAGIBOwACAAAA...', 0)
how do i convert them back to pictures and display them in img tag in ejs, or what other options do i have ,I dont want to change heroku but still be able to display the pictures that the user uploads.
If you are storing your uploaded images in the Heroku server, it is an utter waste. Because Heroku Dyno will restart every day which will delete all the extra added data other than data stored during deployment time.
I think you are using express.
let fs=require("fs")
let yourBuffer=//retrieve that buffer and store into this(yourBuffer) variable
let buffer = new Buffer.from(yourBuffer)
fs.writeFile(`location to storeimage/imagename.yourimageextension`, buffer, "binary", function (err, written) {
if (err) console.log(err);
else {
console.log("Successfully written");
res.sendFile((__dirname + `location of image/imagename.yourimageextension`))
}
});
I think a better solution would be using a 3rd party storage provider, aws s3 for example, and only store image url in the database
My Angular app sends a FormGroup to a Node.js server & then sends that form content via an Email.
At the moment, I can populate the email body like so:
<tr>
<th>Town</th><td>${content['formBody']['personalInfo']['town']}</td>
</tr>
and so on...
But, my form also has a File Upload control which I want to use to add file attachments to the email also.
Here is what I have at the moment:
<td>${content['formBody']['send']['fileUpload']}</td>
But instead of the actual selected file, "object Object" is appearing in the email body currently.
Is there a way I can attach the selected files to the email using the above approach, or is there a different way? Thanks a lot
What are you using in Node.js for getting the files?
A few months ago I needed to upload files and used Multer, a npm package for handling formdata files in node js. With it, you can use the files received on the backend and put it on the email.
In the frontend file
//Method to do the request
superagent
.post(/register")
.attach("avatar", uploadedImage)
uploadedImage has the image content that you get in the VueJS component
In the backend file
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
import fs from 'fs-extra'
router.post('/register', upload.single('avatar'), (req, res, next) => {
return fs.readFile(req.file.path)
.then(content => {
// The content of the file
})
}
For more information, here you have the answer Accessing data sent as FormData using Axios
Does it help?
I am trying to store an image and retrieve it in my application. Storing an image is perfectly working (storing in a specific server path) when it comes to retrieve, the image is not loading into browser until I recompile my angular2 application which is done through nodejs. Below is the code to retrieve an image.
<div class="row" *ngFor="let map of _selectedMaps;let index3 = index;trackBy:trackByIndex;" >
<div class="col-md-1">{{map.id}}</div>
...
<div class="col-md-1"><img class="media-icon" [attr.src]='selectedMapUrl(map)' />
<input type="file" id="fl{{index3}}" class="inputfile" (change)="mapChange($event, map)" placeholder="Upload map" accept=".png,.gif,.jpeg,.jpg" />
<label [attr.for]="'fl'+index3" >Load ...</label>
</div>
.
selectedMapUrl(map) is the method which is generating an URL (URL is generating correctly). I am attaching few screenshots of network and browser source storage.
I am just wondering whats going on, 12600.png will be loaded if I recompile my application.
I observed that whenever I recompile my application browser is reloading and webpack is reloaded.
Can anyone help me resolving.
Thanks...
This is happening because when you uploads an image it is getting upload in project/src/assets/maps but your application is fetching content from dist folder, that is why image is not appearing without compilation ..
because image went to the project/src/assets/maps folder of application not in the project/dist/assets/maps folder ( from where app is using content).
After compile image moved to the dist/assets/map so that is why image started appearing on application, Application is using dist folder's content after compilation. so that is why image appears after re-compile the application.
So it is better to upload image file in dist/assets/map folder too along with project/src/assets/map folder. This way image will start appearing without compilation.
var dir = "src/assets/map";
var distdir ="dist/assets/map";
// image upload code for both locations
if (!fs.existsSync(dir)){
fs.mkdirSync(dir,0775, function(err){
if(err){
fs.mkdirSync(dir);
}
});
}
if (!fs.existsSync(distdir)){
fs.mkdirSync(distdir,0775, function(err){
if(err){
fs.mkdirSync(distdir);
}
});
}
fs.writeFile(dir+"/"+fileName, imageBuffer, {encoding:'utf8'}, function(err) {
if(err)
console.log(err);
});
fs.writeFile(distdir+"/"+fileName, imageBuffer, {encoding:'utf8'}, function(err) {
if(err)
console.log(err);
});
It also maintain image after compilation too.
Thank you!
I had a query that I wanted to ask you about. I was building an application in React-Redux with Express NodeJS as backend, and postgreSQL as db. I wanted to implement a File Upload component into it. Can you please tell me how should I do that ?
Our team had previously implemented file upload in angular using multer on the backend. When we did the same in redux the small files get uploaded fine but when I try to upload a file over 4 mb it re-renders the page before the file is completely uploaded.
Please guide me how should I do this ? If you have a code sample that I can understand, that will also be great.
It is possible to upload multiple files at once in React.
<input type="file" multiple
name="myImage" accept=".png, .jpeg" className="multiple-upload"
onChange={this.uploadScreenshotFile} />
Here is uploadScreenshotFile function
uploadScreenshotFile(event){
for(let size=0; size < event.target.files.length; size++){
console.log('Selected file:', event.target.files[size]);
let file = event.target.files[size];
console.log("uploading screenshot file...");
// Do necessary request to upload here.......
}
}