Reputation: 187
I'm storing references to files in Firebase Cloud Storage using URLs. In firebase client code, you can call firebase.storage().refFromURL(photo.image)
to get the actual storage reference and do handy things like call delete with it. How do I accomplish the same thing in a cloud function (specifically a realtime database trigger)? I want to be able to clean up images after deleting the object that references them.
Upvotes: 13
Views: 3707
Reputation: 38319
In a cloud function, to delete a file from storage you need the file's bucket name and file name (which includes the path). Those can be obtained on the client side from the storage reference. For example, a JS Storage Reference has properties bucket
and fullPath
. The string representation of a storage reference has format: gs://example-12345.appspot.com/path/to/file
, where the bucket is example-12345.appspot.com
and the file "name" is path/to/file
.
In the example cloud function shown below, the client is expected to provide the bucket and filename as children of the trigger location. You could also write the URL string to the trigger location and then split it into bucket and filename components in the cloud function.
This code is based on the example in the Cloud Storage guide.
const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.deleteFile = functions.database.ref('/test').onWrite(event => {
const bucket = event.data.child('bucket').val();
const filename = event.data.child('filename').val();
console.log('bucket=', bucket, 'filename=', filename);
return gcs.bucket(bucket).file(filename).delete().then(() => {
console.log(`gs://${bucket}/${filename} deleted.`);
}).catch((err) => {
console.error('ERROR:', err);
});
});
Upvotes: 2
Reputation: 571
Here is a one-liner.
const refFromURL = (URL) => decodeURIComponent(URL.split('/').pop().split('?')[0])
Upvotes: 2
Reputation: 331
Following Bob Snider's answer, this is a little function (typescript) to extract file full path from URL.
export const getFileFromURL = (fileURL: string): Promise<any> => {
const fSlashes = fileURL.split('/');
const fQuery = fSlashes[fSlashes.length - 1].split('?');
const segments = fQuery[0].split('%2F');
const fileName = segments.join('/');
return fileName;
}
Upvotes: 3
Reputation: 3760
I've wrote code sample which I using instead refFromURL
method from web-firebase in my functions project based on Bob Snyder answer.
function refFromUrl(gsLink) {
var fileEntryTemp = gsLink.file.replace("gs://", "")
var bucketName = fileEntryTemp.substring(0, fileEntryTemp.indexOf("/"));
var filename = gsLink.file.match("gs://" + bucketName + "/" + "(.*)")[1];
var gsReference = admin.storage().bucket().file(filename);
return gsReference;
}
Here is an example how I get a download link based on this ref:
var gsReference = refFromUrl(fileEntry);
gsReference.getSignedUrl({
action: 'read',
expires: '03-09-2491'
}).then(function (url) {
console.log(url);
response.send(url);
}).catch(function (error) {
});
Hope this will save time for somebody
Upvotes: 0
Reputation: 839
For complicated actions on your database from cloud functions you could use Admin SDK https://firebase.google.com/docs/database/admin/start
For the usage of Cloud Storage in Cloud Function check this out https://firebase.google.com/docs/functions/gcp-storage-events
Cloud Functions may not provide the same capability as client since Cloud Functions is beta for now and people are still working on it.
Upvotes: -3