Rarible Clone Part11 Failed to add an item to `itemsForSale`

@classlacia You have used local chain or testnet?

UPD: Local, I see

@Yomoo
Yes!
I use local chain, Ganache.

truffle.config.js

module.exports = {
  networks: {
    development: {
      host: "127.0.0.1", // Localhost (default: none)
      port: 7545, // Standard Ethereum port (default: none)
      network_id: "*", // Any network (default: none)
    },
  },

  mocha: {
    // timeout: 100000
  },

  compilers: {
    solc: {
      version: "^0.8.0",
    },
  },
  db: {
    enabled: false,
  },
};

Hey @classlacia
I’ve just tested smartcontract. It works fine.

Have you seen the video https://www.youtube.com/watch?v=1sAeQ4om01I ?

@Yomoo
Thank you for checking the smart contract.
I have relieved to find out that smart contracts were not the cause.

Yes, I saw the video.
In my moralis dashboard, EthNFTOwners is used instead of NFTTokenOwners in the Part7.5 video.
And it seems that EthNFTOwners has the same data structure of NFTTokenOwners.

@Yomoo

Do I need to add another Cloud Function to sell Items?

I wrote just only one CloudFunction below.

Moralis.Cloud.define("getUserItems", async (request) => {
  const query = new Moralis.Query("EthNFTOwners");
  query.equalTo("contract_type", "ERC721");
  query.containedIn("owner_of", request.user.attributes.accounts);
  const queryResults = await query.find();
  const results = [];
  for (let i = 0; i < queryResults.length; ++i) {
    results.push({
      "id": queryResults[i].attributes.objectId,
      "tokenId": queryResults[i].attributes.token_id,
      "tokenAddress": queryResults[i].attributes.token_address,
      "symbol": queryResults[i].attributes.symbol,
      "tokenUri": queryResults[i].attributes.token_uri,
    });
  }
  return results;
});

Maybe, the plugin setting I wrote is wrong?

abi

{
  "anonymous": false,
  "inputs": [
    {
      "indexed": false,
      "internalType": "uint256",
      "name": "id",
      "type": "uint256"
    },
    {
      "indexed": false,
      "internalType": "uint256",
      "name": "tokenId",
      "type": "uint256"
    },
    {
      "indexed": false,
      "internalType": "address",
      "name": "tokenAddress",
      "type": "address"
    },
    {
      "indexed": false,
      "internalType": "uint256",
      "name": "askingPrice",
      "type": "uint256"
    }
  ],
  "name": "itemAdded",
  "type": "event"
}

Hello, did you manage to solve the problem? I h

Hey @classlacia
Thank you for your patience. It’s hard for me to figure out what the problem is. Some more information is needed.

Are tokens added to the smart contract for sale after calling the function to add items for sale?
Also could you please check again github tutorial Repo. For fast checking you can use diffchecker

I will wait for an answer

1 Like

Hello @Yomoo , with diff
I am in the exact same situation of @classlacia. I have checked all my files with diffchecker and i’m still not able to see items in the section “ItemsForSale” in my dashboard. Which info you need ? Thanks, I have been struggling for a long time without finding the solution…

1 Like

Hey @nicklunik and @classlacia

I just ended testing code from the Tutorial github repo. And it works fine. Only one thing you have to change in the cloud code from the repo NFTTokenOwners -> EthNFTOwners.

Final Cloud Code:

Moralis.Cloud.define("getUserItems", async (request) => {

    const query = new Moralis.Query("EthNFTOwners");
    query.equalTo("contract_type", "ERC721");
    query.containedIn("owner_of", request.user.attributes.accounts);
    const queryResults = await query.find();
    const results = [];
    for (let i = 0; i < queryResults.length; ++i) {
      results.push({
        "tokenObjectId": queryResults[i].id,
        "tokenId": queryResults[i].attributes.token_id,
        "tokenAddress": queryResults[i].attributes.token_address,
        "symbol": queryResults[i].attributes.symbol,
        "tokenUri": queryResults[i].attributes.token_uri,
      });
    }
    return results;
  });
  
  Moralis.Cloud.beforeSave("ItemsForSale", async (request) => {
  
    const query = new Moralis.Query("EthNFTOwners");
    query.equalTo("token_address", request.object.get('tokenAddress'));
    query.equalTo("token_id", request.object.get('tokenId'));
    const object = await query.first();
    if (object){
        const owner = object.attributes.owner_of;
      const userQuery = new Moralis.Query(Moralis.User);
        userQuery.equalTo("accounts", owner);
      const userObject = await userQuery.first({useMasterKey:true});
      if (userObject){
          request.object.set('user', userObject);
      }
      request.object.set('token', object);
    }
  });
  
  Moralis.Cloud.beforeSave("SoldItems", async (request) => {
  
    const query = new Moralis.Query("ItemsForSale");
    query.equalTo("uid", request.object.get('uid'));
    const item = await query.first();
    if (item){
      request.object.set('item', item);
      item.set('isSold', true);
      await item.save();
      
    
      const userQuery = new Moralis.Query(Moralis.User);
        userQuery.equalTo("accounts", request.object.get('buyer'));
      const userObject = await userQuery.first({useMasterKey:true});
      if (userObject){
          request.object.set('user', userObject);
      }
    }
  });    
  
  Moralis.Cloud.define("getItems", async (request) => {
      
    const query = new Moralis.Query("ItemsForSale");
    query.notEqualTo("isSold", true);
    query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id", "user.avatar","user.username");
  
    const queryResults = await query.find({useMasterKey:true});
    const results = [];
  
    for (let i = 0; i < queryResults.length; ++i) {
  
      if (!queryResults[i].attributes.token || !queryResults[i].attributes.user) continue;
  
      results.push({
        "uid": queryResults[i].attributes.uid,
        "tokenId": queryResults[i].attributes.tokenId,
        "tokenAddress": queryResults[i].attributes.tokenAddress,
        "askingPrice": queryResults[i].attributes.askingPrice,
  
        "symbol": queryResults[i].attributes.token.attributes.symbol,
        "tokenUri": queryResults[i].attributes.token.attributes.token_uri,
        "ownerOf": queryResults[i].attributes.token.attributes.owner_of,
        "tokenObjectId": queryResults[i].attributes.token.id,
        
        "sellerUsername": queryResults[i].attributes.user.attributes.username,
        "sellerAvatar": queryResults[i].attributes.user.attributes.avatar,
      });
    }
  
    return results;
  });
  
  Moralis.Cloud.define("getItem", async (request) => {
      
    const query = new Moralis.Query("ItemsForSale");
    query.equalTo("uid", request.params.uid);
    query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id","user.avatar","user.username");
  
    const queryResult = await query.first({useMasterKey:true});
    if (!queryResult) return;
    return {
        "uid": queryResult.attributes.uid,
        "tokenId": queryResult.attributes.tokenId,
        "tokenAddress": queryResult.attributes.tokenAddress,
        "askingPrice": queryResult.attributes.askingPrice,
  
        "symbol": queryResult.attributes.token.attributes.symbol,
        "tokenUri": queryResult.attributes.token.attributes.token_uri,
        "ownerOf": queryResult.attributes.token.attributes.owner_of,
        "tokenObjectId": queryResult.attributes.token.id,
  
        "sellerUsername": queryResult.attributes.user.attributes.username,
        "sellerAvatar": queryResult.attributes.user.attributes.avatar,
      };
  });

  1. Items are added without problems to itemsforsale
  2. Items are shown without problems in user profile
  3. Smart contracts and plugin work without problems.

So, possible solutions of the problem:

  1. Changing in the cloud code NFTTokenOwners -> EthNFTOwners
  2. Check your logs in Moralis Dashboard
  3. Check your Sync and Watch plugin settings
  4. Check your ganache and frpc.exe settings
  5. Check your devchain proxy status:
2 Likes

@Yomoo
Thank you for continuing to be so accommodating!
Also, sorry for taking up so much of your time!

I will proceed as you taught me.

Hello @Yomoo,
Thank you very much for your time. I didn’t notice that my server was disconnected. I knew that it has to be a stupid mistake, and now everything work fine ! Thanks again, Moralis is amazing. Have a great day

1 Like

The only man who makes no mistakes is the man who never does anything.

Happy BUIDLing :man_mechanic:

1 Like

@Yomoo

I created a new Moralis server, redid the Ganache and frp settings, etc. from scratch, and it worked!
Thank you very much.

Moralis is awesome and so are you.

1 Like

Awesome!

Thanks for the kind words!
Happy BUIDLing :man_mechanic:

1 Like

Hey everyone. I’m having an issue where NFTS are minting but not listed in itemsforsale row. User information is being collected. Avatar, email address and everything. NFTs are minting fine. But after I list an item for sale, I don’t see it listed in the itemsforsale row.

What I have noticed is that in the ethNFT owners row the address is identified by “table owner_of string”
Then in the user row their address is identified by “ethAddress String” should these two fields not be listed the same ?

I’ve checked all settings including full re-boot. The only thing I haven’t managed to do is execute the cloud watch file in my project file path. It keeps throwing errors

Here are my cloud function settings.

Moralis.Cloud.define(“getUserItems”, async (request) => {

    const query = new Moralis.Query("NFTTokenOwners");
    query.equalTo("contract_type", "ERC721");
    query.containedIn("owner_of", request.user.attributes.accounts);
    const queryResults = await query.find();
    const results = [];
    for (let i = 0; i < queryResults.length; ++i) {
      results.push({
        "tokenObjectId": queryResults[i].id,
        "tokenId": queryResults[i].attributes.token_id,
        "tokenAddress": queryResults[i].attributes.token_address,
        "symbol": queryResults[i].attributes.symbol,
        "tokenUri": queryResults[i].attributes.token_uri,
      });
    }
    return results;
  });
  
  Moralis.Cloud.beforeSave("ItemsForSale", async (request) => {
  
    const query = new Moralis.Query("NFTTokenOwners");
    query.equalTo("token_address", request.object.get('tokenAddress'));
    query.equalTo("token_id", request.object.get('tokenId'));
    const object = await query.first();
    if (object){
        const owner = object.attributes.owner_of;
      const userQuery = new Moralis.Query(Moralis.User);
        userQuery.equalTo("accounts", owner);
      const userObject = await userQuery.first({useMasterKey:true});
      if (userObject){
          request.object.set('user', userObject);
      }
      request.object.set('token', object);
    }
  });
  
  Moralis.Cloud.beforeSave("SoldItems", async (request) => {
  
    const query = new Moralis.Query("ItemsForSale");
    query.equalTo("uid", request.object.get('uid'));
    const item = await query.first();
    if (item){
      request.object.set('item', item);
      item.set('isSold', true);
      await item.save();
      
    
      const userQuery = new Moralis.Query(Moralis.User);
        userQuery.equalTo("accounts", request.object.get('buyer'));
      const userObject = await userQuery.first({useMasterKey:true});
      if (userObject){
          request.object.set('user', userObject);
      }
    }
  });    
  
  Moralis.Cloud.define("getItems", async (request) => {
      
    const query = new Moralis.Query("ItemsForSale");
    query.notEqualTo("isSold", true);
    query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id", "user.avatar","user.username");
  
    const queryResults = await query.find({useMasterKey:true});
    const results = [];
  
    for (let i = 0; i < queryResults.length; ++i) {
  
      if (!queryResults[i].attributes.token || !queryResults[i].attributes.user) continue;
  
      results.push({
        "uid": queryResults[i].attributes.uid,
        "tokenId": queryResults[i].attributes.tokenId,
        "tokenAddress": queryResults[i].attributes.tokenAddress,
        "askingPrice": queryResults[i].attributes.askingPrice,
  
        "symbol": queryResults[i].attributes.token.attributes.symbol,
        "tokenUri": queryResults[i].attributes.token.attributes.token_uri,
        "ownerOf": queryResults[i].attributes.token.attributes.owner_of,
        "tokenObjectId": queryResults[i].attributes.token.id,
        
        "sellerUsername": queryResults[i].attributes.user.attributes.username,
        "sellerAvatar": queryResults[i].attributes.user.attributes.avatar,
      });
    }
  
    return results;
  });
  
  Moralis.Cloud.define("getItem", async (request) => {
      
    const query = new Moralis.Query("ItemsForSale");
    query.equalTo("uid", request.params.uid);
    query.select("uid","askingPrice","tokenAddress","tokenId", "token.token_uri", "token.symbol","token.owner_of","token.id","user.avatar","user.username");
  
    const queryResult = await query.first({useMasterKey:true});
    if (!queryResult) return;
    return {
        "uid": queryResult.attributes.uid,
        "tokenId": queryResult.attributes.tokenId,
        "tokenAddress": queryResult.attributes.tokenAddress,
        "askingPrice": queryResult.attributes.askingPrice,
  
        "symbol": queryResult.attributes.token.attributes.symbol,
        "tokenUri": queryResult.attributes.token.attributes.token_uri,
        "ownerOf": queryResult.attributes.token.attributes.owner_of,
        "tokenObjectId": queryResult.attributes.token.id,
  
        "sellerUsername": queryResult.attributes.user.attributes.username,
        "sellerAvatar": queryResult.attributes.user.attributes.avatar,
      };
  });

1 Like

Hi @ad01LA

You can find the correct Cloud Functions File above :point_up_2:

Only one thing you have to change in the cloud code from the repo NFTTokenOwners -> EthNFTOwners .

Thank you. After this change in the cloud functions. Minted NFTs now display in “my Items”. However, still no items listed for sale in the coresponding “itemsforsale” row and, it appears as though when i mint NFTs from different address’s in Ganache. All minted items are showing up in “my items”.

Could it be to do with Watch cloud folder not been executed in the correct file path ?
What else could be wrong ?

Hey @ad01LA

Take a look at. I think your NFTs are in the pendingNFTs table and that’s why they doesn’t display in the items for sale:

Take a look at the tutorial how to use watch-cloud-folder