how to get data URL from upload bytes in firesbase? - javascript

How to get data URL from snapshot after uploading to storage in firebase, I cannot find the link in the snapshot, there must be another method to complete the action.
if (input?.files![0]) {
const storage = getStorage();
const storageRef = ref(storage, `profiles/${_authContext.currentUser.uid}/${input?.files![0].name}`);
// 'file' comes from the Blob or File API
uploadBytes(storageRef, input?.files![0]).then((snapshot) => {
console.log(snapshot);
console.log('Uploaded a blob or file!');
});
}

There is another thing you have to do. It's covered in the documentation. Use getDownloadUrl().
getDownloadURL(ref(storage, 'images/stars.jpg'))
.then((url) => {
// `url` is the download URL for 'images/stars.jpg'
}
You can only do this after the upload fully complete.

Related

can you get more than one download URL at once in firestore storage?

I have a path in my bucket that has 10 images can I get the downlead URL of all those 10 images at once in a similar way when you for each doc fields in getDoc() ? or it it stricted to only one at time and to only a specific file name refrence?
const storage = getStorage();
getDownloadURL(ref(storage, 'images/1.jpg'))
.then((url) => {
}
const storage = getStorage();
getDownloadURL(ref(storage, 'images/'))
.then((url) => {
// all the images inside path images/
}

Uploading an mp3 to Firebase Storage with React Native Expo

I am attempting to upload an mp3 to firebase storage using expo and react native. So far I've got the file into firebase storage, but it's only 9bytes large, so I'm doing something wrong. I've attempted this with blob as shown below with no success.
Here is a screenshot of the firebase storage folder showing the file uploaded but not the data of said file:
Any help is greatly appreciated, I feel like I'm missing a step to actually upload the data along with the file.
export default function SongPicker() {
const [song, setSong] = useState(null);
//Get current user through authentication
const user = auth.currentUser;
const pickDocument = async () => {
let result = await DocumentPicker.getDocumentAsync({});
// Fetch the photo with it's local URI
const response = fetch(result.uri);
alert(result.uri);
console.log(result);
const file = new Blob(
[response.value], {
type: 'audio/mpeg'
});
console.log('do we see this?');
try {
//Create the file reference
const storage = getStorage();
const storageRef = ref(storage, `songs/${user.uid}/${result.name}`);
// Upload Blob file to Firebase
const snapshot = uploadBytes(storageRef, file, 'blob').then((snapshot) => {
console.log('Uploaded a song to firebase storage!');
});
setSong(result.uri);
} catch (error) {
console.log(error);
}
}
The fetch() returns a Promise so you should add an await for that as well.
const response = await fetch(result.uri);
Then try using blob() method on the Response:
const file = await response.blob()
The third param in uploadBytes should be upload metadata object but you can skip that here:
const snapshot = await uploadBytes(storageRef, file).

How to get download url for a Image from Firebase Storage?

I am trying to upload an image to firebase storage after that I am trying to get the download url of image but it's not working. Below is the code :
const response = await fetch(selectedImage.uri);
const file = await response.blob();
const storageRef = ref(storage, `profile/${currentUser.email}`);
uploadBytes(storageRef, file).then( (snapshot) => {
console.log('uploaded');
getDownloadURL(storage).then( url => console.log(url)); // tried this outside of then block as well
});
the file is uploaded and accessible through console but getDownloadURL throws error :
[Unhandled promise rejection: TypeError: ref._throwIfRoot is not a function. (In 'ref._throwIfRoot('getDownloadURL')', 'ref._throwIfRoot' is undefined)]
Instead of passing storage to getDownloadURL(), pass snapshot.ref.
const response = await fetch(selectedImage.uri);
const file = await response.blob();
const storageRef = ref(storage, `profile/${currentUser.email}`);
uploadBytes(storageRef, file).then( (snapshot) => {
console.log('uploaded');
getDownloadURL(snapshot.ref).then( url => console.log(url));
});

Image upload, resize and store vue js firebase

I'm using Vue js and firebase for my SPA app. I want to upload image, resize it to fixed dimension and upload it to firebase.
I'm using Jimp npm package to resize the uploaded image.
Below is my code:
Main.js
import Jimp from 'jimp';
Window.Jimp = Jimp;
Snippet that handle upload image
uploadImage(e) {
if (e.target.files[0]) {
let file = e.target.files[0];
Jimp.read(file)
.then(lenna => {
return lenna
.resize(256, 256) // resize
.quality(60) // set JPEG quality
.write(file.name); // save
})
.catch(err => {
console.error(err);
});
conslole.log(lenna);
var storageRef = fb.storage().ref("products/" + file.name);
let uploadTask = storageRef.put(file);
uploadTask.on(
"state_changed",
snapshot => {},
error => {},
() => {
uploadTask.snapshot.ref.getDownloadURL().then(downloadURL => {
this.product.images.push(downloadURL);
console.log("File available at", downloadURL);
});
}
);
}
}
With the above code I get the following error message:
No matching constructor overloading was found. Please see the docs for how to call the Jimp constructor.
Can anyone help me to figure out the mistake I'm making here ?

How to download entire folder from Firebase Storage?

I want to download an entire folder from Firebase storage. I can download single files using DownloadURL as follows, but it does not work for folders.
var storageRef = firebase.storage().ref();
// Create a reference to the file we want to download
var starsRef = storageRef.child(path);
// Get the download URL
starsRef.getDownloadURL().then(function(url) {
// Insert url into an <img> tag to "download"
ImageUrl = url;
console.log(ImageUrl);
}).catch(function(error) {
switch (error.code) {
case 'storage/object_not_found':
// File doesn't exist
break;
case 'storage/unauthorized':
// User doesn't have permission to access the object
break;
case 'storage/canceled':
// User canceled the upload
break;
case 'storage/unknown':
// Unknown error occurred, inspect the server response
break;
}
});
How to download entire folder from Firebase?
You can use gsutil to download the whole storage bucket
gsutil -m cp -R gs://<bucket_name> .
There is no API in Firebase Storage to download all files in a folder. You will have to download the files one by one, or create a zip file that contains all the files.
As Lahiru's answer shows it can be accomplished with gsutils, but that's a server-side operation - not something you'd run in your client-side application.
Related:
How to get a list of all files in Cloud Storage in a Firebase app?
Command gustil for Windows !!!
gsutil cp -r gs://<bucket_name>.appspot.com/OBJECT_NAME "D:\path"
Use Cloud tools for PowerShell
REF for install windows >> https://cloud.google.com/storage/docs/gsutil_install
You can download the folder by creating a zip file of it.
Here is a sample function:
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
import {
getStorage,
listAll,
ref,
getDownloadURL,
getMetadata,
} from 'firebase/storage';
import { auth } from '../../Firebase';
export const downloadFolderAsZip = async () => {
const jszip = new JSZip();
const storage = getStorage();
const folderRef = ref(
storage,
'images'
);
const folder = await listAll(folderRef);
const promises = folder.items
.map(async (item) => {
const file = await getMetadata(item);
const fileRef = ref(storage, item.fullPath);
const fileBlob = await getDownloadURL(fileRef).then((url) => {
return fetch(url).then((response) => response.blob());
});
jszip.file(file.name, fileBlob);
})
.reduce((acc, curr) => acc.then(() => curr), Promise.resolve());
await promises;
const blob = await jszip.generateAsync({ type: 'blob' });
saveAs(blob, 'download.zip');
};
For a recursive solution that includes subfolders in the zip file, see the following sample. You'll instantiate a jszip object, await promises from a function that zips files and traverses the directories, then save the zip. If the content is a file ("item"), it is zipped into the jszip object. If it is a folder ("prefix"), the function is called again with a new subpath, passing in the same jszip object. For further improvement, you may want to get contents with list and pagination if your contents are too many for listAll, since listAll limits retrievals.
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
import {
getStorage, ref, getBlob, listAll,
} from "firebase/storage";
const addFilesFromDirectoryToZip = async (directoryPath = "", zip) => {
const storage = getStorage();
const directoryContentsRef = ref(
storage,
directoryPath
);
const directoryContents = await listAll(directoryContentsRef);
for (const file of directoryContents.items) {
const fileRef = ref(storage, file.fullPath);
const fileBlob = await getBlob(fileRef)
zip.file(file.fullPath, fileBlob);
}
for (const folder of directoryContents.prefixes) {
await addFilesFromDirectoryToZip(folder.fullPath, zip);
};
};
export const downloadFolderAsZip = async (directoryPath = "") => {
const zip = new JSZip();
await addFilesFromDirectoryToZip(directoryPath, zip);
const blob = await zip.generateAsync({ type: "blob" });
const name = directoryPath.split('/').pop();
saveAs(blob, name);
};

Categories