parse-community / parse-server-s3-adapter

AWS S3 file storage adapter for Parse Server

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to delete the actual file from S3 via Parse.Cloud.httpRequest DELETE

grassland-curing-cfa opened this issue · comments

commented

I have successfully configured S3Adapter to upload files to my bucket on S3. It has been successful to use Parse-dashboard to upload a file and asscociate it with a File column called image on my table called item.

A beforeDelete Cloud function is defined as below to delete the uploaded file before a record can be deleted from database.

Parse.Cloud.beforeDelete("item", async (request) => {
	console.log("*** beforeDelete on item");
	
  // Checks if "image" has a value
  if (request.object.has("image")) {

    var file = request.object.get("image");
    var fileName = file.name();
    console.log(file.name());   // This is correct
	console.log(file.url());    // This is correct, too.
	
    const response = await Parse.Cloud.httpRequest({
      method: 'DELETE',
      url: file.url(),
      headers: {
        "X-Parse-Application-Id": "APPLICATION_ID",
        "X-Parse-Master-Key" : "a-super-secret-master-key"
      },
      success: function(httpResponse) {
        console.log('*** Deleted the file associated with the item job successfully.');
        //return httpResponse;
      },
      error: function(httpResponse) {
        console.error('*** Delete failed with response code ' + httpResponse.status + ':' + httpResponse.text);
        //return httpResponse;
      }
    });
	
	console.log("---" + response)
  } else {
    console.log('*** item object to be deleted does not have an associated image (File). No image to be deleted.');
    //return 0;
  }
});

But when I tried to delete an item from my item table, the associated file was not deleted from S3. The ParseServer threw out the following error which I assume is from AWS S3.
<?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>63FC6B3711D87F65</RequestId><HostId>/A3Uoq26QT0dHWnWBttPZJg53fn6+zIVI4rncxeNurIu9fVIbxOJn0GxgvrGVpt+pfZXkopYdQY=</HostId></Error>

What is wrong with my code?

What is the best practise to delete an uploaded file from S3 via ParseServer?

Here's the doc on it: https://docs.parseplatform.org/rest/guide/#deleting-files

It looks like your url value is incorrect. Based on the docs, I think it would be something like:

...
method: 'DELETE',
url: 'https://localhost:8000/parse/files/' + file.url()
...

The way you have it now, you're asking the file to delete itself, instead of asking the rest api to delete the file.

ps: you may need to encode the file.url().....

commented

Thanks for that. I thought the url was supposed to be the url to the file location on S3 as my files are stored on the S3 bucket not on parse.
I tried with url: 'http://localhost:1337/parse/files/' + file.url() as you pointed out but this threw a "404 Not Found" error.
In my case, the file.url() actually returns a full URL to the file on S3, e.g. "https://{MY_BUCKET}.s3.amazonaws.com/ef52295224d5c0600d2e1ba6f0b93ef9_{ORIGINAL_FILE_NAME}.jpg"

commented

Thanks for the effort. But I don't think this solved my problem. The example was for deleting files stored on the pre-migration Parse server (http://files.parsetfss.com) as it was posted back in 2015 before the major migration occurs in 2016. Now that I have migrated to Heroku + MongoDB + AWS S3 stack. The documentation was poorly written in this aspect.

Did you try it? Can you share?

What is written in the docs is accurate, use the ‘name’ of the file and not the full URL of the file.

From the docs:

To delete a file, send a DELETE request to the files URL, postfixed with the name of the file. Note that the name of the file must be the name in the response of the upload operation, rather than the original filename. Note that the X-Parse-Master-Key must be provided in headers.

commented

Thanks @flovilmart ! Did you mean use url: 'http://localhost:1337/parse/files/' + file.name() instead of url: file.url() in the httpRequest options? In my case, the file.name() is like "aacf93479c9b3aecbb165fde16c8169b_{Original_file_name}".

I am starting to wonder if you:

  • read the docs
  • understood the docs
  • applied what is in the docs

In any case, can you point out where in the docs are inaccurate or misleading? Because from what I read, it is both straightforward, clear and concise.

commented

Thanks @flovilmart. I was reading through the JS documentation for Parse and couldn't find anywhere about a working JS example of deleting an already uploaded file.

Here is my revised working code.

                var file = request.object.get("image");
		var fileName = file.name();
		console.log(file.name());
		console.log(file.url());
		
		const response = await Parse.Cloud.httpRequest({
		  method: 'DELETE',
		  url: 'http://localhost:1337/parse/files/' + file.name(),
		  headers: {
			"X-Parse-Application-Id": "Application-Id",
			"X-Parse-Master-Key" : "Master-Key"
		  }
		});

Well, I don’t see anything shared by @acinader that refers to the JS docs.

Did you actually follow the link that was shared above to the docs?

As for your code, I have no idea if it works or not; did you run it? Does it work?

commented

Yes I tried the link that @acinader shared. I was having difficulty getting it to work in JS without an example. I should have read the documentation more broadly. Now the code I posted finally works.

I followed the link @acinader mentioned. The information on that StackOverflow article is either incorrect or outdated.

I posted an update there to what I was able to get working. A big thank you to @grassland-curing-cfa for pointing the way with their questions and revised working code.

@acinader is right, encoding the file name is KEY if you happen to have spaces or other offending characters in your file names.

For anyone that stumbles upon this, visit: https://stackoverflow.com/questions/31146468/delete-parse-file-through-cloud-code