I am having challenge with cloudinary deletion.

Options
Welcome
Welcome Member Posts: 15

const removeProduct = asyncHandler(async (req, res) => {

 try {

  let imageIds = [];

  const { id } = req.params

  const product = await Product.findById({ _id: id });

  if (product) {

   for (let i = 0; i < product.image.length; i++) {

    const deleteImages = await extractPublicId(product.image[i].url);

    imageIds.push(deleteImages);

   };

  }


  if (imageIds.length !== 0) {

   imageIds.forEach(publicId => {

    cloudinary.uploader.destroy(publicId, function (error, result) {

     if (error) {

      console.log('Error deleting image:', publicId, error);

     } else {

      console.log('Deleted image:', publicId, result);

     }

    });

   });

  }


 } catch (error) {

  console.error('error:', error);

  res.json(error)

  //res.status(500).json({ error: "Internal server error please try again." });

 }

});

I am not able to delete images from cloudinary. I am using cloudinary build url to delete images saved in cloudinary but i am always getting "not found". These are the responses:

Deleted image: s--zcVPytYw--/v1711480599/product/ehqya2rrr7pxulc89x9e { result: 'not found' }

Deleted image: s--40Ayaet7--/v1711480596/product/h1jhchfva1fudegw42it { result: 'not found' }

Deleted image: s--vD09pTjl--/v1711480597/product/t7kvszbvugus5xnoitbe { result: 'not found' }

Best Answer

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 124 admin
    Answer ✓
    Options

    Hi there,

    Thank you for the update. I'm glad I could help.

    I will now close this ticket, considering it is resolved. However, if you have any additional questions, please feel free to reply to this message, and the ticket will be automatically reopened.

    If you encounter any further issues or have any other questions, please don't hesitate to contact us through our support center. We are here to assist you.

    Best regards,
    Wissam

    Developer Support Engineer
    Cloudinary


    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights

Answers

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 124 admin
    Options

    Hi there,

    Thanks for reaching out.

    The destroy method takes in the public_id. But you are passing the signature and the version component as well as the public_id. That's why you are getting the error.
    For example, I see that you passed s--zcVPytYw--/v1711480599/product/ehqya2rrr7pxulc89x9e But you should have passed product/ehqya2rrr7pxulc89x9e The s--xxxxxxx-- is the signature and the v12345678 is the version component.

    You can review the documentation for additional information, including syntax examples:
    https://cloudinary.com/documentation/image_upload_api_reference#destroy

    Please give that a try again, passing the correct public_id. Let me know how that goes. If you have any questions, do not hesitate to ask.

    Kind regards,

    Tia

    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights

  • Welcome
    Welcome Member Posts: 15
    Options

    I saved the image urls in the database and I decided to use cloudinary build url library to extract the public ids and save them in an array. After that, I wanted to loop through the public ids to delete the images wihich resulted results above and I do not what to do to remove the signature and version component accompanying the public ids extracted by cloudinary build url. So please help on how to remove those signatures as well as the version component.

  • Welcome
    Welcome Member Posts: 15
    Options

    I saved the image urls in the database and I decided to use cloudinary build url library to extract the public ids and save them in an array. After that, I wanted to loop through the public ids to delete the images which generated the above results or responses and I do not know what to do to remove the signature and version component accompanying the public ids extracted by cloudinary build url. So please help me on how to remove those signatures as well as the version component.

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 124 admin
    Options

    Hi there,

    You can use the Admin API to grab all of the resources in your account. The response object will include the public_id for each asset. So you can write a short script to loop over that and update your database. Then it will be easy to perform deletions or other actions where the public_id is the expected parameter.
    https://cloudinary.com/documentation/admin_api#get_resources
    Can you give that a try and let me know how it goes?

    Otherwise, I'm not familiar with the build url library you mentioned. Is this what you are using?
    https://cloudinary-build-url.netlify.app/usage/extractPublicId

    Kind regards,

    Tia

    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights

  • Welcome
    Welcome Member Posts: 15
    Options

    Thank you for your help.

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 124 admin
    Options

    Hi there,

    You're welcome. If you have additional questions, just let us know.

    Kind regards,

    Tia

    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights

  • Welcome
    Welcome Member Posts: 15
    Options

    I made a change to my code and I am able to store the public id to my database but when I try to delete any image this error pops up

    error: {

    message: 'Stale request - reported time is 2024-03-28 01:44:53+000 which is more than 1 hour ago',

    name: 'Error',

    http_code: 400

    }

  • Welcome
    Welcome Member Posts: 15
    edited March 28
    Options

    I have resolved the issue the stale request error but i am still getting this error "not found" when deleting any image from cloudinary and here is the structure of my database and I was just testing so i did not bother to write any sensible and pardon me for that.

    {

     "_id": {

      "$oid": "66051044f306e94ef86b74ed"

     },

     "name": "Python funtional programming languages",

     "brand": "RockJay",

     "quantity": "6",

     "category": {

      "$oid": "65cec35004a89986e894bd88"

     },

     "description": "sfststsresrfsfsfsfd",

     "rating": 0,

     "numReviews": 0,

     "price": 767,

     "stock": "8",

     "image": [

      {

          "url": "http://res.cloudinary.com/ecoimages/image/upload/s--ZJUKLNyt--/v1711630739/product/wltp2slvtzrhfbs7d7g2.jpg"

      },

      {

          "url": "http://res.cloudinary.com/ecoimages/image/upload/s--Tt-oMT7V--/v1711630741/product/xhhkihgbkdqjlhkbib88.jpg"

      }

     ],

     "imageId": [

      {

       "public_id": "product/wltp2slvtzrhfbs7d7g2"

      },

      {

       "public_id": "product/xhhkihgbkdqjlhkbib88"

      }

     ],

     "reviews": [],

     "createdAt": {

      "$date": "2024-03-28T06:37:56.938Z"

     },

     "updatedAt": {

      "$date": "2024-03-28T06:37:56.938Z"

     },

     "__v": 0

    }


    and this is the backend code which i am trying to use to delete the images:

    const removeProduct = asyncHandler(async (req, res) => {

     try {

      const { id } = req.params

      const product = await Product.findById({ _id: id });

      if (product) {

       for (let i = 0; i < product.imageId.length; i++) {

        cloudinary.uploader.destroy(product.imageId[i].public_id, {

         resource_type: "image", type:

          "authenticated", invalidate: true

        })

         .then((data) => {

          console.log("data: ", data)

         })

         .catch((err) => {

          console.log("error: ", err)

         })


       };

      }


     } catch (error) {

      console.error('error:', error);

      res.json(error)

      //res.status(500).json({ error: "Internal server error please try again." });

     }

    });

    For the image upload, I used cloudinary widget which is specifically for react. I am able to retrieve the image url and public id save them to the database.

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 124 admin
    Options

    Hi there,

    I see the destroy requests that returned an error due to the stale request. I don't see the one(s) that returned 'not found'. Can you confirm if you are still seeing this error when you try to destroy the asset with the public id product/wltp2slvtzrhfbs7d7g2or product/xhhkihgbkdqjlhkbib88

    I look forward to your reply.

    Kind regards,

    Tia

    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights

  • Welcome
    Welcome Member Posts: 15
    Options

    I am able to delete the images only if I do not set authenticated to true (authenticated: true) and I do not understand why it is happening that way. Or is it because I uploaded the image with unsigned preset through your cloudinary widget used in react?

    Here is the response:

    data: { result: 'ok' }
    data: { result: 'ok' }

  • Wissam
    Wissam Member, Cloudinary Staff Posts: 72
    Options

    Hi there,

    I have checked your account ecoimages and I see that all assets have the access control as public and not authenticated and this is why you cannot use the authenticated type in the destroy call.
    You can read more about authenticated assets here :
    https://cloudinary.com/documentation/upload_parameters#authenticated_assets

    I look forward to your reply.

    Kind regards,
    Wissam

  • Welcome
    Welcome Member Posts: 15
    Options

    In fact, I am very grateful for your time as well as helping me to resolve this issue. Thank you.

  • Welcome
    Welcome Member Posts: 15
    Options

    Please how can I update unsigned images using cloudinary nodejs sdk. I used cloudinary react upload widget (client-side) to upload images to my cloudinary account and I don't know if I can use your cloudinary nodejs sdk to update the images.

  • DannyFromCloudinary
    DannyFromCloudinary Member, Cloudinary Staff Posts: 99
    Options

    Thanks for your question.

    By design, it is not possible to overwrite an asset using an unsigned preset. This is to ensure that data isn't lost accidentally.

    If you would like to overwrite an asset, you would need use a signed upload preset, which requires a signature. You can generate the signature either manually, or via one of our SDKs (documentation for this can be found here), however it is imperative to never expose your API secret on the frontend, as anyone with your cloud name, API secret and API key can authenticate as you.

    What I would suggest is to have a backend service that you can query which will generate a signature for you, and then query that service from the frontend, in order to make sure you API credentials are never exposed.

    I hope this helps!

  • Welcome
    Welcome Member Posts: 15
    edited April 20
    Options

    Thank you for your answer. Please, I have also read in your documentation that, I can use explicit method and set the type to upload. Which will update the image. I don't know if I am right. Can you please confirm for me.

  • DannyFromCloudinary
    DannyFromCloudinary Member, Cloudinary Staff Posts: 99
    edited April 20
    Options

    explicit() is meant to perform operations on assets that would usually take place at the time you upload. As it's part of the Upload API and potentially destructive, this also requires a signature to be used.

    What is it you're looking to accomplish?

  • Welcome
    Welcome Member Posts: 15
    Options

    I want to update some of the existing images by uploading new images to replace them.

  • DannyFromCloudinary
    DannyFromCloudinary Member, Cloudinary Staff Posts: 99
    Options

    No problem. To do that, you're not able to use the explicit() method. Instead you will need to use the upload() method of the Upload API, specifying overwrite: true, or use a signed upload preset. As mentioned above in the thread, the best way to use a signed preset from the frontend is by calling a backend service that generates the signature for you.

    Unfortunately, overwriting using an unsigned preset simply isn't possible.

  • Welcome
    Welcome Member Posts: 15
    Options

    So please, you mean I should use the nodejs sdk? Also, will I pass in the public id of the image?

  • DannyFromCloudinary
    DannyFromCloudinary Member, Cloudinary Staff Posts: 99
    Options

    You certainly can do, yes. You would do something like this:

    cloudinary.uploader.upload("/path/to/your/image.ext",
    	{public_id: "public_id_of_the_asset_you_want_to_overwrite",
    	overwrite: true
     	invalidate: true})
    .then(result=>console.log(result))
    .catch(error=>console.warn(error));
    

  • Welcome
    Welcome Member Posts: 15
    Options

    Thank you for your help and I am very grateful for your time.

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 124 admin
    Options

    Hi there,

    I'm glad Danny was able to help 😊 If you have any additional questions, just let us know.

    Kind regards,

    Tia

    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights

  • Welcome
    Welcome Member Posts: 15
    edited April 20
    Options

    I forgot to ask, I am using your solution to solve my problem and I am little confused with this '/path/to/your/image.ext'. Please is it my cloudinary url that I will use to replace this '/path/to/your/image.ext'. I will be glad if you can give a brief explanation about this '/path/to/your/image.ext'.

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 124 admin
    Options

    Hi there,

    This refers to the file you are uploading. It could come from a number of different sources, for example- a local path, a remote URL, a Base64 data URI, etc. You can find more information in our documentation here:
    https://cloudinary.com/documentation/image_upload_api_reference#upload_required_parameters

    These are the file source options that are supported for upload:
    https://cloudinary.com/documentation/upload_parameters#required_file_parameter

    I hope this helps. If you have any questions, do not hesitate to ask.

    Kind regards,

    Tia

    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights

  • Welcome
    Welcome Member Posts: 15
    Options

    Thanks for your awesome explanation. It really concise and I now get it.

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 124 admin
    Options

    Hi there,

    Pleasure 😊 We're always happy to help.

    Kind regards,

    Tia

    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights