Null `metadata` property from `token` APIs

on Rinkbey

Contract: “0x9e91a8ddf365622771312bd859a2b0063097ad34”
Token ID: 3
URI is good, metadata missing

Contract: 0x88b48f654c30e99bc2e4a1559b4dcf1ad93fa656 (OpenSea)
Token ID: 62886929592743516099400483946210518088519633430112237408489058184185662930945
URI is good, metadata missing

Contract: “0xcc14dd8e6673fee203366115d3f9240b079a4930” (Dino)
TokeID: 534
Its URI does not load through the Moralis IPFS
https://ipfs.moralis.io:2053/ipfs/QmNe2Jxm3aqVmByTMdud3z2pDiAYARBfLTEFg1Z7iiK3rj/534.json
Works fine through Cloudflare
https://cloudflare-ipfs.com/ipfs/QmNe2Jxm3aqVmByTMdud3z2pDiAYARBfLTEFg1Z7iiK3rj/316.json

It looks like I also get timeout on that IPFS link now

Yeah On the moralis IPFS

now it looks like it started to work

Yes, but the metadata didn’t update… :frowning:

You might want to keep tasks in the queue until they succeed…

I think you need to read the docs how metadata works: https://docs.moralis.io/misc/faq#why-is-metadata-null-for-some-nfts

Metadata is not guaranteed - it depends on how it’s stored, we can only index reliable decentralized metadata (and even that is not guaranteed atm - we are scaling our systems to index faster)

using token_uri you can resolve yourself in other cases

also - please keep positive tone in forums, when you write a lot of “…” - it’s negative somehow, we are here to help for free its easier if you are more happy :wink:

1 Like

Sorry for the excessive dots. Just trying to help
:grinning: :smiley: :innocent: :fireworks: :fireworks:

hehe perfect, thanks, yes please inform us of all issues you find, we are here to fix :raised_hands::raised_hands:

Keep up the good work :pray:

1 Like

Here’s a fix

I could probably make something much stronger on the server-side if you guys (@cryptokid @ivan) could point me in the right direction

2 Likes

nice sent to Dmitry who is doing the boilerplate maintanance, thanks

resolving token_uri has to be from frontend because a big issue is rate-limits by 3rd party servers holding metadata - backend is gonna get rate limited fast while clients may be able to fetch the token_uri contents they need

This hook also handles the rate limits and retries.

Sure, it’s work, but it would make a speedy UI, which is good UX, which is what makes Moralis so much better then the rest.

So, I might need to develop this on the server anyways and it would probably take me event less time to just improve the existing stuff.

Just a suggestion though. No worries. ╰(°▽°)╯

Thank you @niknak

Amazing work! Already tested and merged :star_struck:

1 Like

Thanks, Dmitry.
Glad I could help!

For anyone who is still unsure on how to bypass metadata and display the URI properties without dismantling your code Moralis provides a very easy way to add and or replace metadata. Look for the useNFTBalance or the useNFTTokenIds hooks in the repository.

Inside the useEffect function you can easily add whatever metadata you want to replace by adding some short lines of code. See below.

useEffect(async () => {
    if (data?.result) {
      const NFTs = data.result;
      setFetchSuccess(true);
      for (let NFT of NFTs) {
        if (NFT?.metadata) {
          NFT.metadata = JSON.parse(NFT.metadata);
          NFT.image = resolveLink(NFT.metadata?.image);
        } else if (NFT?.token_uri) {
          try {
            await fetch(NFT.token_uri)
              .then((response) => response.json())
              .then((data) => {
                NFT.image = resolveLink(data.image);
              });
          } catch (error) {
            setFetchSuccess(false);

This part here is the trick… Use the NFT.image = resolveLink(data.image) as a guideline.

else if (NFT?.token_uri) {
          try {
            await fetch(NFT.token_uri)
              .then((response) => response.json())
              .then((data) => {
                NFT.image = resolveLink(data.image); <------- RIGHT HERE!!
              });

If you want to replace the name of the NFT metadata with the URI name add the name property

NFT.name = resolveLink(data.name);

If you want to replace the description metadata with the URI description add.

NFT.description = resolveLink(data.description);

At the end, your new hook should look something like this.

useEffect(async () => {
    if (data?.result) {
      const NFTs = data.result;
      setFetchSuccess(true);
      for (let NFT of NFTs) {
        if (NFT?.metadata) {
          NFT.metadata = JSON.parse(NFT.metadata);
          NFT.image = resolveLink(NFT.metadata?.image);
        } else if (NFT?.token_uri) {
          try {
            await fetch(NFT.token_uri)
              .then((response) => response.json())
              .then((data) => {
                NFT.image = resolveLink(data.image);
                NFT.name = resolveLink(data.name); <--- REPLACED DATA
                NFT.description = resolveLink(data.description);  <--- REPLACED DATA
              });
          } catch (error) {
            setFetchSuccess(false);

This will automatically pick up any metadata from the metadata source or the URI source “null” or not and display it. I hope this helps for now :slight_smile:

PS You can also add other custom properties that are in the metadata such as external_url and more.

@DevWill Thanks for this!

Is there a way to just push the whole resolved link into the metadata “null” field? ive tried but no luck. The individual elements do show up when tried as in your example


Hello,
I encountered same issue.
I used getAllTokenIds API to get metadata and token_uri.
but both are null. so I can’t show correct images for some token Ids.
I would appreciate if you can let me know how can I fix it.
My email address is
[email protected]
My telegram id
@skyhdev

Thanks
Asato

you can try to use resync metadata endpoint:
https://docs.moralis.io/moralis-server/web3-sdk/token#resyncmetadata

I tried to use resync metadata endpoint.
but still same issue.
please check my code and let me know your opnion.
thanks

can you paste the token_id, chain and contract address?