I am using React Dropzone to upload files from React to firebase as shown below:
const onDrop = useCallback((acceptedFiles, fileRejections) => {
//Check if file type is image
//Check if file size < 5MB
//Upload
if (fileRejections.length > 0) {
setError(true);
} else setError(false);
if (acceptedFiles.length > 0) {
const file = acceptedFiles[0];
console.log(file);
setFile({
...file,
preview: URL.createObjectURL(file),
});
setFileUploaded(true);
}
}, []);
and this is my upload handler:
const handleImageUpload = () => {
//Upload Image to Firebase
//Check if file exists
if (file !== null || file !== undefined) {
const storageRef = ref(
Client.storage,
`/db-dev/user-metadata/portfolio/images/first-image.jpg`
);
console.log('Process begins');
uploadBytes(storageRef, file).then((snapshot) => {
console.log('Uploaded a blob or file!');
});
}
};
these two things do the work but I believe for some reason they're not encoding or decoding the image as in firebase storage folder I see image as invalid image.
Can someone help me to understand where things are going wrong? (To make sure file is loaded properly, I am also viewing the file using: preview: URL.createObjectURL(file), and it loads correctly in browser.
For file upload I am following the latest firebase documentation
It sets file type to octet-stream not sure what that means:
Edit 1: I tried to set metadata to image/jpeg:
uploadBytes(storageRef, file, {
contentType: 'image/jpeg',
}).then((snapshot) => {
console.log('Uploaded a blob or file!');
});
But now it shows:
The problem was in this step:
setFile({
...file,
preview: URL.createObjectURL(file),
});
for some reason it wasn't spreading correctly. I changed it to:
setFile({
file:file,
preview: URL.createObjectURL(file),
});
and the upload function to:
const handleImageUpload = () => {
//Upload Image to Firebase
//Check if file exists
if (file !== null || file !== undefined) {
const storageRef = ref(
Client.storage,
`/db-dev/user-metadata/portfolio/images/first-image.jpg`
);
console.log('Process begins');
uploadBytes(storageRef, file.file, {
contentType: file.file.type,
}).then((snapshot) => {
console.log('Uploaded a blob or file!');
});
}
};
and then it worked fine. Although this was a really silly thing on my part but hope this helps someone in future
Related
I am a newbie and am attempting to display an image that is from my Github profile vs hardcoding it into the HTML. Currently, I have coded the following and the object is being displayed in my Javascript console.
const APIURL = 'https://api.github.com/users/'
getUser('JetimLee')
async function getUser(username) {
try {
const {
data
} = await axios(APIURL + username)
console.log(data)
} catch (err) {
console.log(err)
}
}
My question is - how do I get the image from the profile to be displayed? Thank you so much in advance!
You have an avatar_url field, set it's value as source of an image tag in your html.
Example:
const data = await axios('link');
const imgTag = document.getElementById('git-user-id');
imgTag.setAttribute('src', data.avatar_url);
I faced an interesting question about uploading images at the SailsJS application. I want to upload images from the frontend side to the backend side (NodeJs, SailsJS), validate the image (images), to be sure that images are doesn't include malicious data (like hidden scripts inside image content), and then send this images to AWS storage (S3 bucket)).
On the front end side, everything is done in accordance with SailsJS requirements (text fields are on the top of the form, file on the bottom).
Tools for upload:
For images upload, I use skipper (skipper-better-S3) which is a built-in module in SailsJS. Skipper extends the HTTP body parser used in Sails and Express.
To implement this, I use the code mentioned below:
Vault.read((err, result) => {
if (err) {
console.log('Vault S3 Error', err);
} else {
request.file('logo').upload({
adapter: require('skipper-better-s3'),
key: result.access_key,
secret: result.secret_key,
bucket: sails.config.s3.bucket,
maxBytes: sails.config.globals.multipleMaxLogoSize,
dirname: `some-directory/${client.id}/logo`,
s3config: {
signatureVersion: 'v4',
sslEnabled: true,
sessionToken: result.security_token
},
s3params: {
ACL: 'private',
SSEKMSKeyId: process.env.AWS_S3_KMS_KEY_ARN,
ServerSideEncryption: 'aws:kms',
}
}, (error, uploadedFiles) => {
if (uploadedFiles.length === 0 ? true : Utility.isValidImage(uploadedFiles[0].filename)) {
if (error) {
sails.log.error(error);
return response.serverError();
}
if (uploadedFiles.length > 0) {
uploadedFiles.forEach(uploadedFile => { client.logo = `/logo/${client.id}/${uploadedFile[0].fd.split('/').pop()}`;
client.displayName = request.body.displayName ? request.body.displayName : client.displayName;
client.save().then(() => {
return response.ok({});
}, (error) => {
sails.log.error(error);
return response.serverError(error);
}
)})
} else if (conditionForBadRequest) {
return response.badRequest();
}
} else {
sails.log.error('Invalid Image Type');
return response.badRequest('Invalid Image Type');
}
});
}
})
This code snippet can check if the image has the correct extension (ending), but it doesn't allow us to check if the image includes malicious scripts (Cross-Site Scripting, Persistent XSS).
Based on the mentioned above I have two questions:
How it is possible to check if the uploaded image (it content) includes malicious scripts as we know that image content can be intercepted with the help of some tools (Burp Suite)?
What is the best place for the validation of the image? Maybe it's better to do at saveAs property of request.file('logo').upload() function?
Any help appreciated.
I'm trying to read a pdf and encode it via JS Code in Zapier. Does anyone know how can I encode a Google Drive PDF file?
Trying to do this:
const fs = require('fs');
let buff = fs.readFileSync('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf');
let base64data = buff.toString('base64');
output = [{fileEncoded: base64data}];
But receivingthis error:
Error: ENOENT: no such file or directory, open 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
Any thoughts?
Node's fs module deals with the filesystem, so you can't use it to download files from the web.
Try adapting this example from this github issue:
async function download() {
const res = await fetch('https://assets-cdn.github.com/images/modules/logos_page/Octocat.png');
await new Promise((resolve, reject) => {
const fileStream = fs.createWriteStream('./octocat.png');
res.body.pipe(fileStream);
res.body.on("error", (err) => {
reject(err);
});
fileStream.on("finish", function() {
resolve();
});
});
}
You can use await in Zapier JS without any extra work
How can I store photos in mongodb and display it in my template Dynamically .
I have already created a form which stores the data of the user but I want to fetch the photo and render it through the template . Is there any way to do that ?
MongoDB only showing me C:\fakepath\33783991_259829344578817_7526307875543580672_n.jpg" ! What does that mean ? Is there any working package for meteor file except cloudinary ?
If you don't mind using a package use this one Meteor-Files
It's very easy this is an example below according to the documentation:
Upload form (template):
<template name="uploadForm">
{{#with currentUpload}}
Uploading <b>{{file.name}}</b>:
<span id="progress">{{progress.get}}%</span>
{{else}}
<input id="fileInput" type="file" />
{{/with}}
</template>
Shared code:
import { FilesCollection } from 'meteor/ostrio:files';
const Images = new FilesCollection({collectionName: 'Images'});
export default Images; // To be imported in other files
Client's code:
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
Template.uploadForm.onCreated(function () {
this.currentUpload = new ReactiveVar(false);
});
Template.uploadForm.helpers({
currentUpload() {
return Template.instance().currentUpload.get();
}
});
Template.uploadForm.events({
'change #fileInput'(e, template) {
if (e.currentTarget.files && e.currentTarget.files[0]) {
// We upload only one file, in case
// multiple files were selected
const upload = Images.insert({
file: e.currentTarget.files[0],
streams: 'dynamic',
chunkSize: 'dynamic'
}, false);
upload.on('start', function () {
template.currentUpload.set(this);
});
upload.on('end', function (error, fileObj) {
if (error) {
alert('Error during upload: ' + error);
} else {
alert('File "' + fileObj.name + '" successfully uploaded');
}
template.currentUpload.set(false);
});
upload.start();
}
}
});
By default if config.storagePath isn't passed into Constructor it equals to assets/app/uploads and relative to a running script
On development stage: yourDevAppDir/.meteor/local/build/programs/server. Note: All files will be removed as soon as your application rebuilds or you run meteor reset. To keep your storage persistent during development use an absolute path outside of your project folder, e.g. /data directory.
On production: yourProdAppDir/programs/server. Note: If using MeteorUp (MUP), Docker volumes must to be added to mup.json, see MUP usage
Hint:
You may then use the upload by base64 settings in the insert method
and listen on the onuploaded event to save in your database.
To show the image in your template you may code it like so
<img src="data:image/jpeg;base64,{{ImginBase64}}" class="img-responsive">
Read more about Data URI Scheme
Source : Documentation
You should encode your image in base64, in order to save it in a mongodb document.
Beware to not exceed the 16MB BSON format limit (or use Mongodb's GridFS). In the template you can use the base64 string of the image in the src attribute of the img.
It is better to use an Object storage service like GridFS, S3 or Google Cloud storage, and link it with your Mongo document. Alternatively, you can store your images in base64 format inside the Document itself.
https://forums.meteor.com/t/meteor-secure-file-upload-download-with-s3/38197
There are lot of packages that you can use for this.
I recommend CollectionFS .
You need to add this 3 packages and you're all set .
cfs:standard-packages
cfs:gridfs // storage adapter package . You can change this if you want.
cfs:filesystem
Let's start with Inserting Image.
1. Create ImageCollection.js in your lib folder
import { Mongo } from 'meteor/mongo';
export const BOOK = new Mongo.Collection('books');
var imageStore = new FS.Store.GridFS("images");
export const Images = new FS.Collection("images", {
stores: [imageStore]
});Images.deny({
insert: function(){
return false;
},
update: function(){
return false;
},
remove: function(){
return false;
},
download: function(){
return false;
}
});
Images.allow({
insert: function(){
return true;
},
update: function(){
return true;
},
remove: function(){
return true;
},
download: function(){
return true;
}
})
2. Import Images collection in Client and Server side.
For eg,
import {Images} from '../lib/imageCollection';
3. Add Input type "file" in form and according to your Use.
4. Create a change event in .JS file of that template.
'change #bookCover': function (event) {
event.preventDefault();
console.log("changed!")
var files = event.target.files;
for (var i = 0, ln = files.length; i < ln; i++) {
Images.insert(files[i], function (err, fileObj) {
// Inserted new doc with ID fileObj._id, and kicked off the data upload using HTTP
bookImgId=fileObj._id;
});
}
},
Check in Your Database Image will be inserted.
5. To Display Image Add this HTML where you want to see Image.
6. Add This code in Your js file where you are displaying image.
bookImage: function (id) {
// console.log(id);
var imageBook = Images.findOne({_id:id});
// console.log("img: "+imageBook);
var imageUrl = imageBook.url();
return imageUrl; // Where Images is an FS.Collection instance
}
Note : Make sure you're importing your Book collection where you want display Image.
I am having issues with my google chrome app and filestorage.
The app is run online and gathers files to store offline so that it should be able to function properly offline later. It does this for the most part but sometimes but rarely after a computer restart or restarting the browser it seems to be missing the files in filesystem...
I guess my question is, how do i ensure that Persistent storage remains persistent?
Edit:
Code
Request filesystem
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(
window.PERSISTENT, 200*1024*1024,
function(filesystem) {
directory.fs = filesystem;
//Start Application
},
filesystemerrorHandler
);
Save a File from remote to local filesystem
var xhr = new XMLHttpRequest();
xhr.open('GET', fileurl, true);
xhr.responseType = 'blob';
xhr.send();
xhr.onload = function(e) {
if (this.status == 200) {
var blob = new Blob([this.response], {type: blobtype});
directory.fs.root.getFile(name, {create: true}, function(fileEntry) {
fileEntry.createWriter(function(writer) {
writer.onwrite = function(e) {};
writer.onerror = function(e) { console.log("error"); console.log(e); };
var blob = new Blob([xhr.response], {type: blobtype});
writer.write(blob);
var url = fileEntry.toURL();
if ( typeof(callback) == 'function' ) {
//Save url to indexeddb for recall later
//Returns format of: filesystem:chrome-extension://nlipipdnicabdffnohdhhliiajoonmgm/persistent/xxxxxxxxxxxx.png
callback(url);
}
}, filewriteerrorHandler2);
}, filewriteerrorHandler);
}
else {
if ( typeof(callback) == 'function' ) callback(false);
}
};
Recalling the downloaded file example
<img src="filesystem:chrome-extension://nlipipdnicabdffnohdhhliiajoonmgm/persistent/xxxxxxxxxxxx.png">
Now for the most part this will work. However, sometimes, if the computer has been restarted or the browser restarted. If I use the app again the image will not show, this is giving me the impression that the filesystem has been cleared for this app.
What steps, or what area should I be looking at to prevent this from happening?
Thanks.
Increasing the amount of bytes allocated to the app worked.
I was storing more than i was allocating.
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(
window.PERSISTENT, 200*1024*1024, <====
function(filesystem) {
directory.fs = filesystem;
//Start Application
},
filesystemerrorHandler
);