Caching NFT Token Image in database with cloud functions

Hi all,

I’m looking to store the NFT token image per token Id in the database so that pulling the images will be quicker, however, I’m running into the following issue when trying to “store” the file.

construct.js:25 Uncaught (in promise) Error: File upload by public is disabled.
    at handleError (RESTController.js:435)
    at async updateNFTImages (MyCats.js:28)
    at async onClick (MyCats.js:36)

My cloud function looks approximately like this:

Moralis.Cloud.define("updateNFTImages", async (request) => {
               const NFTImage = Moralis.Object.extend("NFTImage")
               const nftImage = new NFTImage()
// do some stuff, I use web3 to get the nft contract
                let i = 15
                let tokenUri = await nftContract.methods.tokenURI(i).call()
                let tokenUriResponse = await Moralis.Cloud.httpRequest({ url: tokenUri })
                let imageData = await Moralis.Cloud.httpRequest({ url: tokenUriResponse.data.image })
                // I actually don't think this next line is right... but whatever, just trying to see if I can even save a file
                let bufferData = { base64: imageData.buffer.toString('base64') }
                const imageFile = new Moralis.File(`${i}_cat.png`, bufferData)
                nftImage.set("image", imageFile)
                await nftImage.save()
    } 

Is there a better way for me to cache the image of an NFT so I don’t have to read it every time? The api call to get the image is really slow.

For reference, I have a site here: https://jxqtojgfzdkf.grandmoralis.com/

And my images load reeeaaallly slow after minting a cat (work in progress!)

You need to use the masterkey when saving files on the server.
Just use this where you save the object:
await nftImage.save(null, {useMasterKey: true})

2 Likes

This is working! Thank you.

How about files though? I tried the same syntax and getting that error again:

const imageFile = new Moralis.File(`${i}_cat.png`, bufferData)
await imageFile.save(null, { useMasterKey: true })

Hey @PatrickAlphaC

You need to save the file after you’ve created it:

let bufferData = { base64: imageData.buffer.toString('base64') }
const imageFile = new Moralis.File(`${i}_cat.png`, bufferData)
await imageFile.save({ useMasterKey: true });
nftImage.set("image", imageFile);
await nftImage.save(null, { useMasterKey: true });
1 Like

await imageFile.save({ useMasterKey: true }); this line is failing for me, but I’m able to store the image in the database even without this line.

1 Like

It looks like this worked for me:

Moralis.Cloud.define("my_cloud_function", async (request) => {
    let bufferData = { base64: "AAAA" };
    const imageFile = new Moralis.File('1_cat.png', bufferData);
    await imageFile.save({ useMasterKey: true });
    logger.info(imageFile._name);
    logger.info(imageFile._url);
    return imageFile;
});