21

When I delete a post in my Firebase database I want a cloud function to delete the post's thumbnail in firebase storage accordingly. My issue is when I'm trying to delete the thumbnail I don't think I'm locating the image file correctly.

Here is what I have tried:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
const gcs = require('@google-cloud/storage')()

exports.deletePost = functions.database.ref('Posts/{pushId}').onWrite(event => {

  const original = event.data.val()
  const previous = event.data.previous.val()
  const pushId = event.params.pushId

  if (original === null)
    return

  const filePath = 'Posts/' + pushId + 'thumbnail.jpg'
  const bucket = gcs.bucket('postsapp-12312')
  const file = bucket.file(filePath)
  const pr = file.delete()


  return pr
});

This is what I'm getting in logs

ApiError: Not Found at Object.parseHttpRespBody (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:192:30) at Object.handleResp (/user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:132:18) at /user_code/node_modules/@google-cloud/storage/node_modules/@google-cloud/common/src/util.js:465:12 at Request.onResponse [as _callback] (/user_code/node_modules/@google-cloud/storage/node_modules/retry-request/index.js:120:7) at Request.self.callback (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:188:22) at emitTwo (events.js:106:13) at Request.emit (events.js:191:7) at Request. (/user_code/node_modules/@google-cloud/storage/node_modules/request/request.js:1171:10) at emitOne (events.js:96:13) at Request.emit (events.js:188:7)

1
  • require call for gcs, for me only worked as: const gcs = require('@google-cloud/storage'); , thanks to: stackoverflow.com/a/41352560/2162226 Commented Oct 9, 2018 at 3:34

5 Answers 5

17

For anyone else still head-scratching, I was able to get mine deleted by excluding the bucket name (and hence selecting the default firebase bucket):

 const bucket = admin.storage().bucket();
 const path = "path/to/file.wav";
 return bucket.file(path).delete();
Sign up to request clarification or add additional context in comments.

Comments

7

I have managed to fix it. The Issue here was that I was writing my bucket address wrong; it should be something like postsapp-12312.appspot.com instead of postsapp-12312

Update For a better way to put your bucket address check @Robert answer

9 Comments

That one you use to delete is GCS not firebase functions. You are using functions to listening db change and delete via GCS
@vzhen yes ^ it was the only way to do it at the time, has there been any changes now? can you offer a better answer?
I am looking too. I'm using firebase storage not GCS. Seems like firebase admin sdk storage doesn't support server side delete.
Oh my bad, so you are using GCS to delete firebase storage file. Do you store downloadURL for ref in db?
yes, but It's different in my case. the ref is built upon the user uid + the post key + a generated key. and they are all available in the post node so I build the downloadURl from there
|
6

take a look at this functions I have used

const app = admin.initializeApp();

export const onDeleteItem = 
 functions.firestore.document('collectionItems/{collectionID}/items/{itemID}')
   .onDelete((snap, context) => {
     const { collectionID } = context.params;
     const { itemID } = context.params
     return deleteItemImage(collectionID, itemID)
     }
 )

async function deleteItemImage(collectionID: string, itemID: string) {
  const path = `images/${collectionID}/${itemID}`;
  const bucket = app.storage().bucket();
  return bucket.file(path).delete()
    .then(function () {
      console.log(`File deleted successfully in path: ${path}`)
    })
    .catch(function (error) {
      console.log(`File NOT deleted: ${path}`)
    })
}

Comments

5

You can use the firebase functions environment config to get the bucket name:

const bucket = gcs.bucket(functions.config().firebase.storageBucket)

1 Comment

That's a much better way. Thank you very much sir
3

As far as I'm aware, it is not possible to delete firebase storage files from within cloud functions. You can listen to change events on a storage bucket, but you can't interact with it.

The way that I managed this was to remove the 'post' from the database using .set(null). This returns a promise which, when it resolves, you can use to make a delete call to firebase storage.

firebase.database().ref('Posts/{pushId}').set(null).then(() => {
  console.log('Post deleted from database')
  firebase.storage().ref(`Posts/${pushId}thumbnail-image.jpg`).delete().then(() => {
    console.log('Successfully deleted thumbnail');
  }).catch(err => {
    console.log(err);
  });
}).catch(err => {
  console.log(err);
});

Firebase storage won't allow you to recursively delete an entire bucket, so you need to delete each file one-by-one.

1 Comment

Actually, you can, the function I'm using file.delete() works. The issue was that I was writing my bucket address wrong. it should be postsapp-12312.appspot.com instead of postsapp-12312. Sorry that I haven't posted the correct answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.