How to list files and folders in Firebase Storage - firebase

I am working on a school project and have elected to use Firebase as a storage option for uploading/downloading files via an app that I am developing. I would like to be able to display to the user a list of all the files within a specific folder, and also give that user the ability to upload files. However, it seems that the only way to access information within the firebase storage, is to, as the developer, know what the file is rather than find files and display them dynamically. I hope I am making sense with this.
Basically, I would like my app to access the firebase storage, go to a specified folder, and then create a bunch of image-buttons in a viewgroup based off of what is in the folder without having to know before hand what to expect.
Would this be possible via metadata? As in, when ever a new file/folder is created within this parent folder, could I also programmatically update that parent folder's metadata to say, "hey there are these specific files within this folder?"

var storage = firebase.storage();
// Create a storage reference from our storage service
var storageRef = storage.ref();
// Create a child reference
var imagesRef = storageRef.child('yourMainFolder');
// Find all the prefixes and items.
imagesRef.listAll()
.then((res) => {
res.items.forEach((itemRef) => {
itemRef.getDownloadURL().then(function (url) {
console.log(url)
}).catch(function (error) {
// Handle any errors
});
});
res.prefixes.forEach((folderRef) => {
console.log("folder", folderRef._delegate._location.path_.split('/')[1])// In my case:)
});
}).catch((error) => {
// Uh-oh, an error occurred!
});

Currently there is no API in Firebase Storage to list all files in a folder.
What you can do is maintain a database of metadata information (such as file names and folder names) somewhere else.
Firebase Realtime Database would be a good choice for this task.

Related

Insufficient permissions issue while deploying a firebase function [duplicate]

I'm trying to trigger my function on specific path in storage bucket using:
exports.generateThumbnail = functions.storage.bucket("users").object().onChange(event => {});
When I try to deploy it, console shows:
functions[generateThumbnail]: Deploy Error: Insufficient permissions to (re)configure a trigger (permission denied for bucket users). Please, give owner permissions to the editor role of the bucket and try again.
How can I do that? Do I nedd to setup IAM or bucket permission or maybe something else?
Looks like the issue is that you're trying to reference a bucket named "users" rather than filtering on an object prefix.
What you want is:
exports.generateThumbnail = functions.storage.object().onChange(event => {
if (object.name.match(/users\//)) {
// do whatever you want in the filtered expression!
}
});
Eventually we want to make prefix filtering available so you can do object("users"), but currently you have to filter in your function like above.

Flutter - Uploading Image to Firebase Storage

I am trying to create an admin application that can select and upload an image to the Firebase storage and after that, I want the image URL to automatically reflect in the document that is sending data to the client-side application.
The only problem with this is that I only know how to upload an image to Firebase storage from the admin application. I haven't figured a way, as to how can I get the image URL into my document in Cloud Firestore.
Any suggestions or direction regarding this will be helpful.
I am using the flutter framework.
Database structure :
SkinTreatment :
"SkinTreatment": {
"someDocumentName": {
"title": "Threading",
"packageDetails":"This package will provide you with normal upper EyeBrow Threading",
"price" : "200"
"duration": "75mins"
},
"someDocumentName2": { ... },
"someDocumentName3": { ... }
}
You can certainly write code to write the path and/or URL of a file in Cloud Storage to any database. If you have a StorageReference object representing a file that was uploaded, you can use its getPath() method to get a path to the file in storage, and you can use getDownloadUrl() to asynchronously get a download URL as well.
For help writing data to Firestore, there is plenty of documentation.

How should I save references to firebase storage objects?

Store references by name (users/1/profile.png). Then the URL needs to be generated all the time.
const url = await firebase
.storage()
.ref('users/1/profile.png')
.getDownloadURL()
Store references by URL. The access token could be revoked which would cause issues trying to generate a new one and update it in the database.
const url = await firebase
.storage()
.refFromURL(invalidURL)
.getDownloadURL()
Related to #1. Store by file name only so files can be moved without having to update database references.
const url = await firebase
.storage()
.ref(`users/${user.id}/${user.image}`)
.getDownloadURL()
The download URL and the reference path are two different things and I'd store each of them as appropriate (and sometimes both).
Store the Download URL when you want to directly serve the file from storage (e.g. an <img> tag).
Store the Reference Path when you need to keep a reference to the file to modify it later.
Calling getDownloadURL() does trigger a network request and so it's advisable to cache the result when possible to avoid unnecessary extra work/latency.

Uploading by firebase storage

I tried to uplad (multi photos) using firebase storage (site) and it upladed successfully but I can NOT find it in database section anywhere and also it do not appear in application.
How can I upload multi photos by firebase site and appear on database section and also my application?
Thank you
Firebase storage and realtime database are two different entities, so after uploading image to firebase storage you need to save the download url in realtime database on your own, at path of your choice, in the following example, images url are being saved at images path
var uploadTask = storageRef.child('images/rivers.jpg').put(file);
uploadTask.on('state_changed', function(snapshot){
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
}, function(error) {
// error uploading file
}, function() {
// File uploaded successfully, now store the download url in realtime database
uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) {
console.log('File available at', downloadURL);
firebase.database().ref('images').set({
image:downloadURL
});
});
});
before saving images url in realtime database make sure you have enabled realtime database for your project
You can't save photos directly in the realtime-database. After you upload the photos get the URLs and save them in the realtime-database.

What is the difference between mediaLink and SignedUrl in firebase storage

I have a firebase function to upload files to firebase storage, after upload I have to return the url (as Reset response) so that user can view the file
const bucket = admin.storage().bucket();
const [file, meta] = await bucket.upload(tempLocalFile, {
destination: uploadPath,
resumable: false,
public: true,
});
I have two options
1- const signedUrl = await file.getSignedUrl({ action: 'read', expires: '03-09-2491' });
2- meta.mediaLink
SignedUrl will be like https://storage.googleapis.com/web-scanner-dev.appspot.com/pwc%2Fwww.x.com%2F2019-11-17%2Fdesktop%2Fscreenshot-2019-11-17-1125.png?GoogleAccessId=firebase-gcloud%40scanner-dev.iam.gserviceaccount.com&Expires=16447035600&Signature=w49DJpGU9%2BnT7nlpCiJRgfAc98x4i2I%2FiP5UjQipZQGweXmTCl9n%2FnGWmPivkYHJNvkC7Ilgxfxc558%2F%2BuWWJ2pflsDY9HJ%2Bnm6TbwCrsmoVH56nuGZHJ7ggp9c3jSiGmQj3lOvxXfwMHXcWBtvcBaVj%2BH2H8uhxOtJoJOXj%2BOq3EC7XH8hamLY8dUbUkTRtaWPB9mlLUZ78soZ1mwI%2FY8DqLFwb75iob4zwwnDZe16yNnr4nApMDS7BYPxh4cAPSiokq30hPR8RUSNTn2GxpRom5ZiiI8dV4w%2BxYZ0DvdJxn%2FW83kqnjx6RSdZ%2B9S3P9yuND3qieAQ%3D%3D
and mediaLink will be like https://storage.googleapis.com/download/storage/v1/b/web-scanner-dev.appspot.com/o/pwc%2Fwww.x.com%2F2019-11-17%2Fdesktop%2Fscreenshot-2019-11-17-1125.png?generation=1574007908157173&alt=media
What is the pros and cons of each?
The mediaLink does not convey any access permissions on its own -- thus, the object itself will need to be publicly readable in order for end uers to make use of the link (or you will need to be authenticated as an account with read access to that bucket when you execute the link).
On the other hand, a URL returned by getSignedUrl will have a signature that allows access for as long as the URL hasn't expired. Thus, the link alone is sufficient (if temporary) permission to access the blob. Additionally, the URL that is generated maintains the permissions of the user who created it -- if that user loses access to the blob before the link would otherwise expire, the link will no longer function.

Resources