Upload file from AWS to collection

Hi!

I’m trying to find a way to upload a PDF that is stored on an AWS server into a collection.
I have the URL and I’ve tried to do a wix-data save() with the URL as a value for the field in the collection that is a “file” field, but the url is just considered a string.

Does anyone have experience with this?

And I have also tried to use an UploadButton but I can’t seem to set the url of what to upload, it has to be the user who chooses a file.

If you want to move the physical file from one server to another, I would try this:

  1. GET the file first using wix-fetch and store it in a var
  2. map it to a db-collection (field) and .save() it

Thanks Giri, I’ll give it a try!

Hi @giri-zano

Would you be able to look at this code? I can’t figure out how to get the response from the fetch to be something that I can save() into the collection (or update())
I get a successful get with code 200 though.

I have made a backend code to work with and am using a specific item in my collection to play with.
Here’s a test URL https://www.c3f.org/userfiles/filemanager/1010/

export function getPDFfromAWS(fetchUrl) {
    fetch(fetchUrl, {
        "headers": {
        "Content-Type": "application/pdf"
        },
    "method": "get",
    "mode": 'no-cors',
    })
    .then( (httpResponse) => {
        let url = httpResponse.url;
        let statusCode = httpResponse.status;
        let statusText = httpResponse.statusText;
        let headers = httpResponse.headers;
        let bodyUsed = httpResponse.bodyUsed;
        var body = httpResponse.body;
    if (httpResponse.ok) {
        console.log(statusCode + " " + statusText);
            let toUpdate = {
                "_id":          "f5ea6533-ad44-40a1-a1f6-1f5cc5d94ac5",
                "applicationPdf":   body,

            };
        
           wixData.update("GrantApplications", toUpdate)
            .then( (results) => {
                let item = results; //see item below
                console.log(item)
            } )
    .catch( (err) => {
        let errorMsg = err;
        console.log(err)
     } );

        return httpResponse;
        }
     else {
            return Promise.reject("Fetch did not succeed");
     }
    } )
    .catch( (err) => {
        console.log("error "+err);
    } );
}

I´m sure you checked it, but I have to ask: 1) is the field “applicationPdf” defined as type “File” in Collectio? 2) have you checked Permissions (or overrule them with suppressAuth) on the Collection?

Hi Giri!

Haha you can never be too sure.
Yes the field type is file, and I can write to it, however it is just the java string with all the attributes in it…

Hi Giri! Here’s what I keep getting in the collection field.
Here what I get from the fetch:

  1. 200
    status:

  2. “OK”
    statusText:

  3. headers:
    {…}

_headers:
{…}

server:
[…]

date:
[…]

content-type:
[…]

content-length:
[…]

x-guploader-uploadid:
[…]

expires:
[…]

cache-control:
[…]

last-modified:
[…]

etag:
[…]

x-goog-generation:
[…]

x-goog-metageneration:
[…]

x-goog-stored-content-encoding:
[…]

x-goog-stored-content-length:
[…]

x-goog-meta-origin:
[…]

x-goog-hash:
[…]

x-goog-storage-class:
[…]

accept-ranges:
[…]

access-control-allow-origin:
[…]

access-control-expose-headers:
[…]

timing-allow-origin:
[…]

x-seen-by:
[…]

x-robots-tag:
[…]

via:
[…]

alt-svc:
[…]

connection:
[…]

  1. true
    ok:

  2. body:
    {…}

  3. false
    bodyUsed:

  4. 0
    size:

  5. 0
    timeout:

  6. _raw:
    Array(0)

  7. false
    _abort:

The red underline at field level ususally indicated the value doesn´t match the required format. If you hover over it, do you get a pop-up description of the error. Otherwise, you can usually click that field and see the whole contents (that {"_readableState …). Could you copy it here? And when do you get it? When you retrieve the pdf and try to write the content into that field?

Hi Giri. I’m sorry for the long respond time. I don’t always get notifications on this forum. I appreciate your time very much!

Here’s the error:

However, the field itself is over 36.000 lines, so I can’t copy the contents in here.
But here’s the first few lines:

{
  "body": {
    "_readableState": {
      "decoder": null,
      "defaultEncoding": "utf8",
      "ended": false,
      "autoDestroy": false,
      "pipes": null,
      "endEmitted": false,
      "awaitDrain": 0,
      "reading": false,
      "emittedReadable": false,
      "buffer": {
        "length": 13,
        "tail": {
          "next": null,
          "data": {
            "type": "Buffer",
            "data": [

It’s the data attribute that’s huge.

The above is what I get in the httpresponse and what I try to save into the collection. Here’s the full code. I run it in the backend.
I get status code 200 which is successful.

export async function getPDFfromAWS(fetchUrl) {
fetch(fetchUrl, {
"headers": {
"Content-Type": "application/pdf"
},
"method": "get",
"mode": 'no-cors',
})
.then( (httpResponse) => {
let url = httpResponse.url;
let statusCode = httpResponse.status;
let statusText = httpResponse.statusText;
let headers = httpResponse.headers;
let bodyUsed = httpResponse.bodyUsed;
var body = httpResponse.body;
if (httpResponse.ok) {
console.log(statusCode + " " + statusText);
let toUpdate = {
"_id":          "f5ea6533-ad44-40a1-a1f6-1f5cc5d94ac5",
"applicationPdf":   httpResponse,

};
wixData.save("GrantApplications", toUpdate)
.then( (results) => {
let item = results; //see item below
console.log(item)
} )
.catch( (err) => {
let errorMsg = err;
console.log(err)
} );
console.log(httpResponse)
return httpResponse;

}
else {
return Promise.reject("Fetch did not succeed");
}
} )
.catch( (err) => {
console.log("error "+err);
} );
}

Hi Anders. I don´t know, I´m not familiar with the internals of the PDF-file structure. We can go on trying things, but I will bump this up to the Masters Forum, see if anyone else has experience with this.

I think that would be great! Do you have a link to that forum?

No, it´s a private forum. I posted it there, give it a day, ok?

Hi Anders,

There is a tiny issue in your code:

let toUpdate = {
"_id":          "f5ea6533-ad44-40a1-a1f6-1f5cc5d94ac5",
"applicationPdf":   httpResponse,

};

What you are saving is the HttpResponse object of Fetch (that’s where all those properties come from). Not the actual PDF data.

The data needs to be read from the response first, then safely encoded to a string that can be stored in the database.

Something like

fetch('url-of-some-pdf')
  .then(response => response.body.getReader().read())
  .then(body => {
    const base64Body = btoa(String.fromCharCode.apply(null, body.value))
    wixData.save('pdfStore', { _id: '...', applicationPdf: base64Body})
})

When reading the data, applicationPdf fields can be converted back to binary using atob function.

However, note that Wix Data has a limit of 0.5MB for a single document. Long documents or documents that contain images can grow larger than this limit.

Some relevant documentation:

1 Like

Hello Anders

I haven’t yet tested the following code
Here is the idea, that might be helpful

AWS send the PDF in base64 String

and you can use Wix fetch to get the PDF(in base64 String)
And using Wix media backend manager you can upload the file and get the wix URL and saved it on the database as a Wix URL or save it just as a base64 String. that depends on your purpose

// Sample code to get the file from AWS as a base64
// upload to Wix database and store it as Wix URL

import { mediaManager } from 'wix-media-backend';
import wixData from "wix-data";

export async function getPDFfromAWS(fetchUrl) {
try {
const headers = { "Content-Type": "application/pdf"}
const fetchOpts = {"headers": headers,"mode": 'no-cors'};
const httpRes = await fetch(fetchUrl, fetchOpts);
if(!httpRes.ok) throw new Error("Status is not okay : ", httpRes);
const pdfBuffer = await httpRes.buffer();

// convt buffer to base64
const pdfBase64 = `data:application/pdf;base64, ${pdfBuffer.toString('base64')}`;

const toSaveID = "f5ea6533-ad44-40a1-a1f6-1f5cc5d94ac5";
let toUpdate = {
"_id" : toSaveID,
"applicationPdf" : pdfBase64
}

/* below code to upload base64 to wix and get wix URL*/
let uploaded = await uploadPDF(pdfBuffer, "AWS pdf")
console.log({uploaded});
// "pdfURL"  is a fieldkey 
toUpdate.pdfURL = uploaded.fileUrl; 
/* above code to upload base64 to wix and get wix URL*/

return wixData.update("GrantApplications", toUpdate);
}
catch(e) {
// handle error
console.log({e});
}
}
/*
Article link
https://www.wix.com/corvid/reference/wix-media-backend.mediaManager.html#MediaOptions
*/
export function uploadPDF(buffer, name="unknown") {
const mediaOpt =  {
"mediaOptions": {
"mimeType": "application/pdf",
"mediaType": "document"
},
"metadataOptions": {
"isPrivate": false,
"isVisitorUpload": false
}
}
const fileName =`${name}.pdf`;
const folderPath = "/pdf";
return mediaManager.upload(folderPath,buffer,fileName,mediaOpt);
}


Links
upload :mediaManager - Velo API Reference - Wix.com

let me know if there is any typo in the reply

Note you cannot use upload button. Only way to upload to wix server is using wix media backend.

Thanks, @giedrius-grazevicius and @admin51915 for stepping in.

Thank you so much @giri-zano and @admin51915 ! This is amazing!!
It works!! I get the file fetched and uploaded to the MediaManager, however in the collection I get this error


As soon as I click Change to File it converts to a PDF file - but until then I can’t open it.
Any ideas?

Hi @anders
Good to know you get the PDF in the base64 format
you will need to run “uploadPDF( buffer , name =“unknown”)”
which will convert the PDF buffer to wix URL and store the url in the
“pdfURL” fieldkey (You will need to create a column with that field key)

Let me know if that fixed your issue

1 Like