Get Download Url after firebase's resize extension completed - javascript

This is what I am trying to achieve, implement the firebase's resize image extension, upload an image, then when the resize is completed, add that dowloadUrl's thumbs to a Cloud Firestore document. This question helps me, but still can not identify the thumbs and get the download URL, this is what am have been trying so far.
Note: I set my thumbnail to be at root/thumbs
const functions = require('firebase-functions');
const { Storage } = require('#google-cloud/storage');
const storage = new Storage();
exports.thumbsUrl = functions.storage.object().onFinalize(async object => {
const fileBucket = object.bucket;
const filePath = object.name;
const contentType = object.contentType;
if (fileBucket && filePath && contentType) {
console.log('Complete data');
if (!contentType.startsWith('thumbs/')) {
console.log('This is not a thumbnails');
return true;
}
console.log('This is a thumbnails');
} else {
console.log('Incomplete data');
return null;
}
});

Method 1 : Client Side
Don't change the access token when creating the thumbnail.
Edit the function from gcloud cloud function console
Go to the function code by clicking detailed usage stats
Then click on code
Edit the following lines
Redeploy the function again
// If the original image has a download token, add a
// new token to the image being resized #323
if (metadata.metadata.firebaseStorageDownloadTokens) {
// metadata.metadata.firebaseStorageDownloadTokens = uuidv4_1.uuid();
}
Fetch the uploaded image using getDownloadURLfunction
https://firebasestorage.googleapis.com/v0/b/<project_id>/o/<FolderName>%2F<Filename>.jpg?alt=media&token=xxxxxx-xxx-xxx-xxx-xxxxxxxxxxxxx
Because the access token will be similar
https://firebasestorage.googleapis.com/v0/b/<project_id>/o/<FolderName>%2Fthumbnails%2F<Filename>_300x300.jpg?alt=media&token=xxxxxx-xxx-xxx-xxx-xxxxxxxxxxxxx
Method 2: Server Side
Call this function after thumbnail is created
var storage = firebase.storage();
var pathReference = storage.ref('users/' + userId + '/avatar.jpg');
pathReference.getDownloadURL().then(function (url) {
$("#large-avatar").attr('src', url);
}).catch(function (error) {
// Handle any errors
});

you need to use filePath for checking the thumbs
if(filePath.startswith('thumbs/'){...}
contentType has the metadata of files like type of image and etc.
FilePath will have the full path.

Related

How to get file name from download link in firebase storage(Javascript, React)?

I've being trying to get files name from Firebase storage.
Right now I got a download link and trying to get name from it.
const showPhoto = () => {
var eventDOM = event.target;
var src = eventDOM.getAttribute('src');
setpickImage(src);
console.log(src);
// src = "https://firebasestorage.googleapis.com/v0/b....."
}
I need file name to delete file from storage.
If you want to map a download URL back to a file name, use the refFromURL method.
Also see the documentation on creating a reference from a download URL, which contains this example:
var httpsReference = storage.refFromURL('https://firebasestorage.googleapis.com/b/bucket/o/images%20stars.jpg');
From that Reference you can then get other properties like the file's name.
let fileName = httpsReference.name;
To get the file name and url or download link of the videos or files from the firebase storage you can use these two functions in javascript and react
// function to fetch videos / files from firebase storage
const fetchVideos = async() => {
const storageRef = firebase.storage().ref("your storage folder name");
const videos = [];
await storageRef
.listAll()
.then(async function(result) {
result.items.forEach(async function(videoRef) {
// getting the name of the file
const videoName = videoRef.name;
// getting the url of the file -> calling another function for this
const videoUrl = await getVideoUrl(videoRef);
// creating the object with name and url
const videoObj = {
videoName,
videoUrl,
};
console.log("video obj", videoObj);
videos.push(videoObj);
});
})
.catch(function(error) {
// Handle any errors
return [];
});
}
// function to get download url
const getVideoUrl = (imageRef) => {
const videoLink = imageRef
.getDownloadURL()
.then(function(videoUrl) {
console.log("videoUrl", videoUrl);
return videoUrl;
})
.catch(function(error) {
// Handle any errors
return "";
});
return videoLink;
};

Node.js createWriteStream 'finish' called late

I have a Google Cloud Function hosted on Firebase which takes an image URL from Twilio and, using pipe(), uploads the image to a bucket on GCS. This works, however I want to call another function once the image has been successfully uploaded. I have a .on('finish') to trigger another function, however in looking at logs, it appears the finish is being called almost a minute after the file has actually finished uploading. I can physically see the image in my GCS console well before the finish function is called.
What might be the cause of this delay?
const mediaUrl = request.body.MediaUrl0;
const contentType = request.body.MediaContentType0;
const extension = mime.extension(contentType);
global.filename = Date.now() + "." + extension;
console.log("Filename: " + filename);
//Save image to gcs bucket
const gc = new Storage({
projectID: 'testProject-rgjdxr'
});
const bucketName = 'msg-images';
const bucket = gc.bucket(bucketName);
const file = bucket.file(filename);
const w = file.createWriteStream({
metadata:{
contentType: contentType
}
});
pollRequest(mediaUrl).auth(accountSid, authToken).pipe(w).on('finish', () => {
global.gcsUrl = `https://storage.cloud.google.com/${bucketName}/${filename}`;
console.log(gcsUrl);
//I can see this log, however the timestamp is about 60sec
//after the file was uploaded successfully to GCS bucket.
analyzeImage(gcsUrl); //passing image url to another function
});

Download multiple files using S3 pre-signed url in my Angular Application

I am making REST API call to get an array of pre-signed URLs from S3. These URL are files that could be XML, CSV, JSON etc.
How do I loop download files from these URLs without opening a new tab?
I do not want to use AWS SDK for NodeJS to avoid tight coupling with my front-end. Application currently has Angular 7, NodeJS and ExpressJS.
getFile(url, params){
this.awsservice.getFile(url, params).subscribe(
(response) => {
const res = JSON.parse(JSON.stringify(response));
var apiList = [];
for (var key in res) {
if(key == 'api'){
apiList = res[key];
}
}
apiList.forEach(function (url) {
// Logic to download file
document.location.assign(url) //Only seems to download the last file in the array
console.log("Download started: "+url);
});
},
(error) => {
this.tempErrorFlag = true;
const errorMsg = error;
console.log(`ERROR ::: reInitiate API ::: ${errorMsg.message}`);
});
}
I tried adding document.location.assign(url) but it only seems to download the last url in the array. Even adding delay didn't help.
Appreciate your help.
I was able to download the files but not in the same tab. First I fetch presigned URLs from my angular service, which I feed into an array. Then basically with each of the presigned urls, I create a temporary anchor tag to and assign href the presigned url value. The snackbarService is for showing a popup when the download begins. The entire code looks like below:
downloadItem() {
let urls = [];
for(let item of this.selectedRowsData) {
//calling the service to fetch the presigned url
this.dataService.getPresignedToDownloadAll(
item.value,
item.id).subscribe((res) => {
urls.push(res);
this.download(urls);
});
}
}
download(urls: any) {
var self = this;
var url = urls.pop();
setTimeout(function(){
self.snackBarService.loadComponent({
isSuccess: true,
message: MESSAGES.downloadInProgress,
});
var a = document.createElement('a');
a.setAttribute('href', url);
document.body.appendChild(a);
a.setAttribute('download', '');
a.setAttribute('target', '_blank');
a.click();
// a.remove();
}, 1000)
}

code for getting the url picture in storage and put in database of firebase

var selectedFile;
$("#file").on("change", function(event) {
selectedFile = event.target.files[0];
$("#uploadButton").show();
});
function uploadFile() {
// Create a root reference
var filename = selectedFile.name;
var storageRef = firebase.storage().ref('/dogImages/' + filename);
var uploadTask = storageRef.put(selectedFile);
// Register three observers:
// 1. 'state_changed' observer, called any time the state changes
// 2. Error observer, called on failure
// 3. Completion observer, called on successful completion
uploadTask.on('state_changed', function(snapshot){
// Observe state change events such as progress, pause, and resume
// See below for more detail
}, function(error) {
// Handle unsuccessful uploads
}, function() {
// Handle successful uploads on complete
// For instance, get the download URL: https://firebasestorage.googleapis.com/...
var postKey = firebase.database().ref('Posts').push().key;
var downloadURL = uploadTask.snapshot.downloadURL;
var postData = {
url: downloadURL,
caption: $("#imageCaption").val()
};
var updatess = {};
updatess ['Posts' + postKey] = postData;
return firebase.database().ref().update(updatess);
});
}
The Error is Uncaught (in promise) Error: Reference.update failed: First argument contains undefined in property 'Posts-LRyHOS3r8-VP-7WMsCS.url' and it doesnt store in database of firebase. this is my code
The error message is quite explicit: downloadURL seems to be null. If you search for recent questions about this, you'll see that the download URL is now retrieved asynchronously by calling getDownloadURL().
So something like:
uploadTask.on('state_changed', function(snapshot){
// Observe state change events such as progress, pause, and resume
// See below for more detail
}, function(error) {
// Handle unsuccessful uploads
}, function() {
var postKey = firebase.database().ref('Posts').push().key;
var downloadURL = uploadTask.snapshot.downloadURL;
return storageRef.getDownloadURL().toPromise().then(downloadUrl => {
var postData = {
url: downloadUrl,
caption: $("#imageCaption").val()
};
var updatess = {};
updatess ['Posts' + postKey] = postData;
return firebase.database().ref().update(updatess);
});
});
Also see:
the Firebase documentation sample on uploads
the Firebase documentation on downloading files by URL
How do i get download URL once upload is done on firebase storage
Firebase get Download URL after successful image upload to firebase storage
I can't get image downloadUrl from Firebase Storage (Angular/Ionic)

Upload a photo to Firebase Storage with Image URI

I am currently attempting to upload a photo to my Firebase app's storage in my Apache Cordova app. I currently get the photo's URI with the following code:
function getPhotoFromAlbum() {
navigator.camera.getPicture(onPhotoURISuccess, onFail, {
quality: 50,
sourceType: navigator.camera.PictureSourceType.SAVEDPHOTOALBUM,
destinationType: navigator.camera.DestinationType.FILE_URI
});
}
function onPhotoURISuccess(imageURI) {
var image = document.getElementById('image');
image.style.display = 'block';
image.src = imageURI;
getFileEntry(imageURI);
}
And then am attempting to convert the image into a file and push it to my Firebase storage with the following function:
function getFileEntry(imgUri) {
window.resolveLocalFileSystemURL(imgUri, function success(fileEntry) {
console.log("got file: " + fileEntry.fullPath);
var filename = "test.jpg";
var storageRef = firebase.storage().ref('/images/' + filename);
var uploadTask = storageRef.put(fileEntry);
}, function () {
// If don't get the FileEntry (which may happen when testing
// on some emulators), copy to a new FileEntry.
createNewFileEntry(imgUri);
});
}
I have both the file and the camera cordova plugins installed, the only errors I get when I attempt to do this is
Error in Success callbackId: File1733312835 : [object Object]
Which is just an error message from cordova.js
I also know I have my Firebase storage set up correctly because I have tested it through an emulator by adding a file input and successfully uploading whatever file the user added, to the Firebase storage.
Is it possible to upload a file to Firebase storage using this method of converting an image to a file through its URI, and then uploading it? If so, what is the correct way to do so / what is wrong with the way i'm doing it?
I was able to accomplish uploading an image by using a data url. Below is my code:
var filename = "test.jpg";
var storageRef = firebase.storage().ref('/images/' + filename);
var message = 'data:image/jpg;base64,' + imageUri;
storageRef.putString(message, 'data_url').then(function (snapshot) {
console.log('Uploaded a data_url string!');
});
Is it possible to upload a file to Firebase storage using this method of converting an image to a file through its URI, and then uploading it? If so, what is the correct way to do so / what is wrong with the way i'm doing it?
Yes it is possible to upload a file on firebase through its URI. However you have to follow the correct way.
1. You have to store the data in firebase after file reading operation is completed.you can use FileReader.onloadend for this.
2. By using a data_url you can store to firebase.
Here is the snippet for more clarity:
function getFileEntry(imgUri) {
window.resolveLocalFileSystemURL(imgUri, function onSuccess(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function() {
filename = "test.jpg";
var storageRef = firebase.storage().ref('/images/' + filename);
var data = 'data:image/jpg;base64,' + imgUri;
storageRef.putString(data, 'data_url').then(function (snapshot) {
console.log('Image is uploaded by base64 format...');
});
};
reader.readAsArrayBuffer(file);
});
},
function onError(err) {
console.log(err);
createNewFileEntry(imgUri);
});
}

Categories

Resources