Reputation: 134
I have a ReactJS application that allows a user to choose a file using File Uploader and upload it to Firebase Storage (not Database). These uploads are stored in a directory called 'sorts'. The user can upload a PDF, image, a WebM, etc. I'm trying to list all files found in storage on the UI but I am having issues. I think there is a way to do it with Firebase Database but not too sure if it's possible with Firebase Storage. I've tried following the documentation download files via web but I couldn't really get it working. Most of what I've found online is only displaying one file from storage, not a list of all the files. At the moment, I am able to get a list of the download URLs for each file in the form of: https://firebasestorage.googleapis.com/v0/b/algorithms-visualiser-react.appspot.com/o/sorts%2Fvideo_956493.webm?alt=media&token=07b18ccf-3e3d-4a1f-88b5-193528f0cf09. Issue comes when I try to list all these on the actual UI (whether that be an actual visual representation of each file or simply a list of all the downlad URLs which, when clicked on, would download the file).
Below is the relevant code:
Uploading:
handleUploadStart = () => {
this.setState ({
progress: 0
})
}
handleUploadSuccess = filename => {
this.setState ({
sort: filename,
progress: 100
})
firebase.storage().ref('sorts').child(filename).getDownloadURL()
.then(url => this.setState ({
videoURL: url
}))
}
Render function (includes how each download link is retrieved and how files are uploaded)
render() {
const { classes } = this.props;
console.log(this.state);
var i = 0;
let displayFile = '';
const sorts = [];
$('#Sorts').find('tbody').html('');
firebase.storage().ref().child('sorts/').listAll().then(function(result) {
result.items.forEach(function(fileRef) {
i++; // Counter for each file in storage
fileRef.getDownloadURL().then(function(fileURL) {
console.log(fileURL);
sorts.push(fileURL);
})
});
});
return (
<div className="App">
<SortsToolbar history={this.props.history} />
<FileUploader
accept="*"
name="video"
storageRef={firebase.storage().ref('sorts')}
onUploadStart={this.handleUploadStart}
onUploadSuccess={this.handleUploadSuccess} />
<br />
{sorts.items.map((item, index) => (
<li key={index} item={item} />
))}
</div>
);
}
As mentioned, if I could simply find a way to list all these download links in a list on the UI side, it'd be something. Any help will be appreciated.
Upvotes: 1
Views: 2676
Reputation: 556
This is an example of how to get urls without using getDownloadURL
. What I am doing is using a list from storage reference of the required folder, then adding the needed prefixes instead of slash which firebase needs. Therefore, without using getDownloadURL
I am getting all the urls.
storageRef.listAll().then(function (result) {
let path = storageRef.fullPath
path = path.replace(/\b\/\b(?!.*?\b\/\b)/, "%2F");
result.items.forEach(fileRef => {
temp.push({name: fileRef.name, url: path + "%2F" + fileRef.name +"?alt=media" })
});
}).then(()=>{
// set data in your any state variable for later use
setData(temp)
}).catch(error => {
console.log(error);
})
Upvotes: 1
Reputation: 317467
getDownloadURL
is the only way to get a URL from a file in Cloud Storage, and it only works on one file at a time. There is no bulk operation for this.
You can try to list the files you want with the list API, but you will still have to iterate that list and call getDownloadURL
on each one of them.
For tasks like this, storing the URLs in a database and query that is typically the easier and faster way to go.
Upvotes: 2