0

I would like to delete files from my storage.

And for that I need the UID from the request ref.orderByChild('timestamp').endAt(cutoff);

I already have a function for deleting child nodes, but I want to delete at the same time the picture in my storage.

Screenshot of my database :

enter image description here

My cloud functions for Firebase ( I found the code here Delete firebase data older than 2 hours and here https://github.com/firebase/functions-samples/tree/master/delete-old-child-nodes ) :

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');

// The Firebase Admin SDK to access Cloud Firestore.
var admin = require("firebase-admin");

var serviceAccount = require("./serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://XXXXXX.firebaseio.com",
  storageBucket: "gs://XXXXX.appspot.com",
});

var defaultStorage = admin.storage();

// Cut off time. Child nodes older than this will be deleted.
const CUT_OFF_TIME = 24 * 60 * 60 * 1000; // 24 Hours in milliseconds.

/**
 * This database triggered function will check for child nodes that are older than the
 * cut-off time. Each child needs to have a `timestamp` attribute.
 */
exports.deleteOldItems = functions.database.ref('/images/{pushId}').onWrite(async (change) => {
  const ref = change.after.ref.parent; // reference to the parent
  const now = Date.now();
  const cutoff = now - CUT_OFF_TIME;
  const oldItemsQuery = ref.orderByChild('timestamp').endAt(cutoff);
  const snapshot = await oldItemsQuery.once('value');


  // EDIT#2

  snapshot.forEach((child) => {

        const uid = child.key;
        const re = admin.database().ref('images/'+uid);
        const img = re.child('image');

        const bucket = defaultStorage.bucket();
        const file = bucket.file(img);

    // Delete the file
        return file.delete();
    })

  // END EDIT#2

  // create a map with all children that need to be removed
  const updates = {};
  snapshot.forEach(child => {
    updates[child.key] = null;
  });
  // execute all updates in one go and return the result to end the function
  return ref.update(updates);
});

I have already tried to get the value of "image" but I have No such object: XXXXX.appspot.com/https://XXXXX.firebaseio.com/images/undefined/image

Thank you in advance for your help.

EDIT#1

Thanks to Doug Stevenson, I changed the value of "image" for having the good path.

EDIT#2

Thank you Ralemos, I iterate it with a foreach but now I have a new error : Error: No such object: XXXXX.appspot.com/https://XXXXX.firebaseio.com/images/-M9OeGPXB-KqEVqxZYCb/image And I don't understand why because the value is not null.

Chaotix
  • 21
  • 6
  • 1
    Your image string is a download URL generated by a client SDK for Cloud Storage. However, the Admin SDK for Cloud Storage doesn't understand these download URLs. I suggest storing a normal path to the file and using that to delete the object instead. For example: /path/to/image.jpg – Doug Stevenson Jun 07 '20 at 17:45
  • Okay, thank you, I’ll see about the path, and for the UID, do you have a suggestion or any solution ? Thank you. – Chaotix Jun 07 '20 at 19:59
  • Doug's comment already offers a solution for you issue with the path of the file you want to delete in the bucket. I did not understood what problem you are facing with the UID, since by what you wrote on the question it only references the deletion of files, can you clarify? – Ralemos Jun 08 '20 at 12:33
  • In my question I said I couldn’t get the value of "image" because I can’t get the UID. I make a request for the "timestamp" and I need the UID of it but cannot get it and I need it to get the value of "image". I hope that’s clear enough for you – Chaotix Jun 08 '20 at 13:06
  • From what I understood of your code, your `oldItemsQuery` variable is a list of all the documents that need to be deleted, ordered by timestamp, correct? If that is the case, why don't you iterate it with a foreach for example? With that, you get each individual document uid of this list and do whatever you need to do with it that value. – Ralemos Jun 09 '20 at 13:55
  • Thank you Ralemos, I iterate it with a foreach but now I have a new error : ``Error: No such object: XXXXX.appspot.com/https://XXXXX.firebaseio.com/images/-M9OeGPXB-KqEVqxZYCb/image `` And I don't understand why because the value is not null – Chaotix Jun 09 '20 at 16:40
  • Is `XXXXX.appspot.com/https://XXXXX.firebaseio.com/images/-M9OeGPXB-KqEVqxZYCb/image` your object or it's value? If it is the value, this is weird, cause you appear to have part of a storage path (`XXXXX.appspot.com`) and a url (`https://XXXXX.firebaseio.com/images/-M9OeGPXB-KqEVqxZYCb/image`) in the same value. This could be part of the issue. Also, can you share the code changes you made? This would make it easier to find what the issue is. – Ralemos Jun 10 '20 at 15:10
  • This is my object and the value is "/photo-send......", I edit the code in my post. – Chaotix Jun 11 '20 at 10:49
  • Can you share an example image url from your storage? I don't see how you can reach it on storage with the information you currently have stored, woudn't it be easier to create a field called imageUrl in your Firestore and store the url in there? – Ralemos Jun 16 '20 at 13:52

0 Answers0