Firebase change file name on download - javascript

I want to download a file but before that i would like to remove the prefix I've put
Current Code:
getDownloadURL(ref(storage, props.fullPath))
.then((url) => {
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = (event) => {
const blob = xhr.response;
};
xhr.open('GET', url);
xhr.send();
window.open(url, '_blank', 'noreferrer').focus();
})
.catch((error) => {
console.log("download file error ", error)
});
E.g:
file name in database:
Data.csv7d931632-a562-4d7c-9b9c-d00a90a545e0
file name on download:
Data.csv

Related

React Native: Retrieve image URL from firestore

This is a function that uploads an image to the firebase storage and then retrieves the URL using the 'getDownloadURL' function.
The uploading of images works fine but it fails to retrieve the URL as it is trying to access the URL while the image is still uploading.
Please solve this problem !!
const getGSTURI = async () => {
if (GSTLoading) {
return;
}
setGSTLoading(true);
const result = await DocumentPicker.getDocumentAsync({
copyToCacheDirectory: true,
});
console.warn(result);
setGSTName(result.name);
setGSTURI(result.uri);
setGSTLoading(false);
async function uploadGST(uri, name) {
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
console.warn(e);
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", uri, true);
xhr.send(null);
});
const storageRef = ref(storage, `sellers/${sellerID}/${name}`);
uploadBytes(storageRef, blob).then(() => {
console.warn("GST Upload Successfull");
});
getDownloadURL(ref(storage, `sellers/${sellerID}/${name}`))
.then((url) => {
// `url` is the download URL for 'images ' stored in firestorage
console.log(url);
setGSTURL(url);
console.log(GSTURL);
})
.catch((error) => {
"Errors while downloading";
});
// We're done with the blob, close and release it
blob.close();
}
uploadGST(GSTURI, GSTName);
};
you have to wait for the uploadBytes function to complete before trying to retrieve the url
instead of
uploadBytes(storageRef, blob).then(() => {
console.warn("GST Upload Successfull");
});
you can use the await operator as below to wait for the task to complete
try {
await uploadBytes(storageRef, blob);
console.warn('GST Upload Successfull');
} catch (e) {
console.warn('GST Upload Failed', e);
}

How to upload an image in firebase version 9?

I'm trying to update the version 8 code to version 9, but the image that is uploaded yields Error loading preview ...
Here is the code:
async storeImage(img: { uri: string; base64: string }, userId: string) {
try {
let imageUrl = null;
const imageName = img.uri.substring(img.uri.length - 40);
const imageRef = ref(this.storage, `profile-images/${userId}/${imageName}`);
uploadString(imageRef, img.base64, 'base64', { contentType: "image/jpg" }).then((snapshot) => {
console.log("image stored", snapshot);
})
getDownloadURL(ref(this.storage, `profile-images/${userId}/${imageName}`))
.then(url => {
const xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = (event) => {
const blob = xhr.response;
};
xhr.open('GET', url);
xhr.send();
console.log('getDownloadURL', url);
imageUrl = url;
})
return imageUrl
} catch (error) {
console.log(error);
}
}
}
The uri string is the address on the device, the base64 is
/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAyKADAAQAAAABAAAAhAAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZ...
This is the url from the firebase storage preview.
This is the downloaded url, which should be the same as the above.
I tried also in uploadString to use base64url but nothing.
Any kind of help would be appreciated.
Thanks in advance.

put the data from an api link using this function and console.log it

I want to use a variable which has the JSON data to later parse and stringify it
all i want now is to see the actual array of objects in the console!
console.log(fetchJSON('url'));
function fetchJSON(url, cb) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = () => {
if (xhr.status < 400) {
cb(null, xhr.response);
} else {
cb(new Error(`Network error: ${xhr.status} - ${xhr.statusText}`));
}
};
xhr.onerror = () => cb(new Error('Network request failed'));
xhr.send();
}
I expect the output of console.log(fetchJSON('url'));
to be
Try this:
fetchJSON('url', function(result) {
console.log(result);
});
Your function fetchJSON is returning a callback function. If you want to return just the result change
this
cb(null, xhr.response);
to:
return xhr.response;

GET request from browser works to download file to local but XMLHttpRequest Javascript script does not download file

I'm having trouble with XMLHttpRequest I think, when I navigate to localhost/dashboard/downloadfile?file-name=hw3.txt the file downloads locally but If I use the function checkDownload() to start an XMLHttpRequest the file does not get downloaded.
Here is my client code:
function checkDownload() {
const filename = "hw3.txt";
const xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.open('GET', `/dashboard/downloadfile?file-name=${ filename }`);
xhr.onreadystatechange = () => {
if(xhr.readyState === 4) {
if(xhr.status === 200) {
}
}
}
xhr.send();
}
And then here is my server code:
app.get('/dashboard/downloadfile', requiresLogin, (req, res) => {
const userid = req.user.id;
const filename = req.query['file-name'];
db.getFileKey([userid, filename], (keyres) => {
const params = {
Bucket: S3_BUCKET,
Key: keyres.rows[0].filekey,
};
res.setHeader('Content-disposition', `attachment; filename=${ filename }`);
res.setHeader('Content-type', `${ mime.getType(keyres.rows[0].filetype) }`);
s3.getObject(params, (awserr, awsres) => {
if(awserr) console.log(awserr);
else console.log(awsres);
}).createReadStream().pipe(res);
});
});
I got it working. Instead of trying to create a read stream from s3.getObject() I generated a signed url to the s3 object on the server and returned that to the client, then used an 'a' html element with element.href = signedRequest and used javascript to click that element. The new problem I'm running into is that I can't figure out a way to set the metadata for the s3 object when it is initially uploaded, I needed to manually change the metadata on an individual s3 object through the aws console so that it had the header Content-Disposition: attachment; filename=${ filename }.
changed client code:
function initDownload(filename) {
const xhr = new XMLHttpRequest();
xhr.open('GET', `/sign-s3-get-request?file-name=${ filename }`);
xhr.onreadystatechange = () => {
if(xhr.readyState === 4) {
if(xhr.status === 200) {
const response = JSON.parse(xhr.responseText);
startDownload(response.signedRequest, response.url);
}
}
}
xhr.send();
}
function startDownload(signedRequest, url) {
var link = document.createElement('a');
link.href = signedRequest;
link.setAttribute('download', 'download');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
changed server code:
app.get('/sign-s3-get-request', requiresLogin, (req, res) => {
const userid = req.user.id;
const filename = req.query['file-name'];
db.getFileKey([userid, filename], (keyres) => {
const s3Params = {
Bucket: S3_BUCKET,
Key: keyres.rows[0].filekey,
Expires: 60,
};
s3.getSignedUrl('getObject', s3Params, (err, data) => {
if (err) {
// eslint-disable-next-line
console.log(err);
res.end();
}
const returnData = {
signedRequest: data,
url: `https://${S3_BUCKET}.s3.amazonaws.com/${ keyres.rows[0].filekey }`,
};
res.write(JSON.stringify(returnData));
res.end();
});
});
});
You are getting a blob back from the server, so in order to download you need to do something when xhr.status === 200.
Something like this:
...
if(xhr.status === 200) {
var fileUrl = URL.createObjectURL(xhr.responseText)
window.location.replace(fileUrl)
}
...
To download having the URL you could use the attribute download of a tag:
<a download="something.txt" href="https://google.com">Download Google</a>
If you use xhr.responseType = "blob", you have to do somethig like:
function checkDownload() {
const filename = "hw3.txt";
const xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
xhr.onreadystatechange = () => {
if(xhr.readyState === 4) {
if(xhr.status === 200) {
var reader = new FileReader();
reader.readAsArrayBuffer(xhr.response);
reader.addEventListener("loadend", function() {
var a = new Int8Array(reader.result);
console.log(JSON.stringify(a, null, ' '));
});
}
}
}
xhr.send();
}
checkDownload()
But that code doesn't download the file.

Upload image to firebase from hybrid app

how can I upload an image from his path "file:///var/mobile/Containers/Data/Application/D6326867-A474-481F-B6B4-5A9A6251CC0E/tmp/cdv_photo_013.jpg" to firebase storage using Javascript ? Cause I know how to using Blob or File but not from a single path...
Here my resolved code :
uploadPicutre(uri:string, userUid: string){
let self = this;
return new Promise((resolve, reject) => {
function toDataUrl(url, callback) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
callback(xhr.response);
};
xhr.open('GET', url);
xhr.send();
}
toDataUrl(uri, blob => {
self.refStoragePicture.child(userUid)
.put(blob).then(snapshot => {
self.refStoragePicture.child(userUid)
.getDownloadURL().then(function(url) {
resolve(url);
}).catch(function(error) {
reject(error);
});
}).catch( err => {
reject(err);
});
})
})
}

Categories