1

I used Angular, Ionic and Firebase in my project. I used Uploadcare to upload and retrieve photos to the application. I can delete the file in the database but the problem is the actual image is still uploaded in the UploadCare Storage.

Heres my code:

organization.service.ts - this is where I connect the application in the Firebase and UploadCare

RESPONSE I GOT:

From the service: Response from the service.

From the page.ts: Response from the page.ts

UPDATE

RESPONSE IN NETWORK:

This is my Network Activity while Deleting an Item with an Image. enter image description here

organization.service.ts

  deleteOrg(orgId: string){
    return this.http
    .delete(`https://db-student-portal-default-rtdb.firebaseio.com/add-organization/${orgId}.json`)
    .pipe(switchMap(() => {
      return this.allOrg;
    }),
    take(1), 
    tap(orgs => {
      this.organization.next(orgs.filter(o => o.id !== orgId))
    })
    );
  }

  //This is the function to delete the image in UploadCare
  deleteImage(image: any){

    let httpHeader = new HttpHeaders();
    
    httpHeader.set('Authorization', `Uploadcare.Simple ${PUB_KEY}:${SEC_KEY}`);
    httpHeader.set('Accept', 'application/vnd.uploadcare-v0.5+json');

    this.http.delete(`https://api.uploadcare.com/files/${image}/`, {headers: httpHeader});
  }

organization.page.ts

  onDeleteOrg(){
    this.alertCtrl.create({
      header: 'Delete ' + this.loadedOrg.orgName,
      message: 'Do you want to delete this organization?',
      buttons: [
      {
        text: 'Cancel',
        role: 'cancel'
      },
      {
        text: 'Delete',
        handler: () => {
          this.loadingCtrl.create({
            message: 'Deleting Organization: ' + this.loadedOrg.orgName,
            spinner: 'circular'
          }).then(loadEl => {
            loadEl.present();
            
            //THIS IS WHERE THE DELETION HAPPEN (in the Firebase)
            this.orgService.deleteOrg(this.loadedOrg.id).subscribe(() => {
           //THIS IS WHERE THE DELETION HAPPEN (in the UploadCare)
              this.orgService.deleteImage(this.loadedOrg.imageUrl.replace('https://ucarecdn.com/', ''));
              loadEl.dismiss();
              this.router.navigate(['/homepage']);
            });
          });
        }
      }]
    }).then(alertEl => {
        alertEl.present();
    });

  }

2 Answers2

0

According to the docs, UploadCare's single file delete only requires the file's UUID, ie delete /files/:uuid (see https://uploadcare.com/docs/rest-api/accessing-files/#delete-file).

As far as I can tell, you're trying to pass the whole file data to the API which semantically wouldn't be correct anyway (it uses the uuid to match the correct files).

Adapting your code to something like

let httpHeaders = new HttpHeaders();
httpHeaders.set('Authorization', 'Uploadcare.Simple');
httpHeaders.set('UPLOADCARE_PUB_KEY', '6b*****************7');
this.httpClient.delete(`https://api.uploadcare.com/files/${uuid}/`, { headers: httpHeaders })

should do the trick.

Edit: I feel like there's a bit more explanation needed. What you're trying to do you with your code is to call UploadCare's delete endpoint. According to the docs, that endpoint requires the to be deleted file's uuid, ie /files/:uuid as well as Authorization and UPLOADCARE_PUB_KEY headers. For that you use HttpHeaders.

In your version, you were passing that data as part of a FormData object (see docs) which should throw an HTTP404 error I imagine.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Aldin Bradaric
  • 733
  • 3
  • 10
  • thanks for answering sir. As you can see in this line of code I pass the uuid of the image: `this.orgService.deleteImage(this.loadedOrg.imageUrl.replace('https://ucarecdn.com/', ''));`. And I pass it here: ` return this.http.delete(`https://api.uploadcare.com/files/${data}/`);` – John Paulo A. Geronimo Jan 15 '21 at 11:44
  • What you pass in `data` is a FormData object containing multiple things. But what the delete endpoint expects is only the uuid of the file you want to delete. But first things first-- could you edit your original post and include the response you get after calling UploadCare's delete endpoint? – Aldin Bradaric Jan 15 '21 at 11:52
  • Sir I edited the post and add the response. As you can see the url of image was replaced by blank to extract uuid only. – John Paulo A. Geronimo Jan 15 '21 at 12:06
  • I edited my answer. Try that version and see how that goes. If it doesn't work, edit your post again and include the response you get from UploadCare's backend (ie. what you see in your browser's Network tab). We'll take it from there if necessary. – Aldin Bradaric Jan 15 '21 at 12:30
  • I edited the code sir with the response in Network Tab. But DELETE response is not existent in the Network Tab. – John Paulo A. Geronimo Jan 15 '21 at 13:55
  • You need to have your Network tab open, ideally delete any existing entries, and then execute your code. And assuming no error happens beforehand, you should see some network activity. – Aldin Bradaric Jan 15 '21 at 15:17
  • I open the tab and screenshot the whole activity when deleting an item. This is the whole activity I added in the post. – John Paulo A. Geronimo Jan 15 '21 at 15:41
0

The Simple authorization scheme requires you to provide both public and secret API keys (see Uploadcare REST API reference). You should modify your code this way

let httpHeaders = new HttpHeaders();
httpHeaders.set('Authorization', `Uploadcare.Simple ${YOUR_PUBLIC_KEY}:${YOUR_SECRET_KEY}`);
httpHeaders.set('Accept', 'application/vnd.uploadcare-v0.5+json');
this.httpClient.delete(`https://api.uploadcare.com/files/${uuid}/`, { headers: httpHeaders });

Note that implementing the file deletion logic on the frontend is insecure and is not recommended because it exposes your secret key. You should implement it in your app's backend so that a user of your app can't get access to the request details that include the secret key, or use the token-based Uploadcare auth scheme.

  • i try that code above sir. But DELETE response is not existent in the Network Tab – John Paulo A. Geronimo Jan 15 '21 at 13:54
  • My response above was intended to show you how to build the request properly (which endpoint to use, and which headers to set). Sorry, I'm not an Angular expert, and perhaps there's something in your code that needs to be fixed to make it send the request. – Alex Chernenko Jan 20 '21 at 12:07
  • Thank you for helping sir. But is this line of code especially the Secret_Key is applicable in Community Package of Uploadcare or is this only applicable if you pay? – John Paulo A. Geronimo Jan 20 '21 at 13:30
  • Uploadcare REST API is available to users regardless of the plan. So if you are subscribed to the free Community plan, you can use this API method as well as any other ones. – Alex Chernenko Jan 21 '21 at 14:16