Ganache, sync and Watch Contract Event gets added to database only after second call

Hello
Im working on a NFT marketplace, I tested the same code with server versions 0.0.330 and 0.0.334, on 0.0.330 everything works fine, on 0.0.334 every event its not added to database after first call. For example I create an nft and then I call the method from the contract to put it to sale, in ganache I see the transaction worked fine and emiting the event but the data it does not appear in database, the data appear in database only after I put it to sale again and get the error from MetaMask that the item its already on sale(error from smart contract), this time in ganache, the transaction its not emiting the event anymore but the item its now added to database. This was working fine on 0.0.330 server, I didnt have any problems and I did several tests to be sure that this is the cause.

Thank you for you time and hope you can help me

maybe the problem is related to the fact that you may need to do more transactions in ganache in order to consider last transaction as validated, you could try to make a simple transfer after you do that contract transaction

Yes, if I do any transaction after I call the contract, the last transaction where I put the nft to sale its added to database by the event sync but when I run the app on 0.0.330 server version, its beeing added without any other transactions needed after it

can you try with the new Nitro version? Moralis Nitro Beta Testing

Its not wokring on Nitro version either and I tried again on 0.0.335 and its not working. Only on 0.0.330 it works, Im pretty sure its a server problem

P.S: this is happening to all the sync events I have in my smart contracts

Here is a part of my code, maybe you can help me(this works on 0.0.330):

sync event:

when an item is added to market

topic: artworkAdded(address,address,uint256,uint256,uint256,bool)

{
  "anonymous": false,
  "inputs": [
    {
      "indexed": false,
      "internalType": "address",
      "name": "tokenAddress",
      "type": "address"
    },
    {
      "indexed": false,
      "internalType": "address",
      "name": "seller",
      "type": "address"
    },
    {
      "indexed": false,
      "internalType": "uint256",
      "name": "price",
      "type": "uint256"
    },
    {
      "indexed": false,
      "internalType": "uint256",
      "name": "tokenId",
      "type": "uint256"
    },
    {
      "indexed": false,
      "internalType": "uint256",
      "name": "offerId",
      "type": "uint256"
    },
    {
      "indexed": false,
      "internalType": "bool",
      "name": "isSold",
      "type": "bool"
    }
  ],
  "name": "artworkAdded",
  "type": "event"
}
contract address: 0x2CE9c0E11332551848CF40836e617641Be8bF8B5
tablename: ArtworkForSale

cloud function:

Moralis.Cloud.beforeSave("ArtworkForSale", async (request) => {
  const query = new Moralis.Query("Artwork");
  query.equalTo("tokenAddress", request.object.get('tokenAddress'));
  query.equalTo("nftId", request.object.get('tokenId'));
  const object = await query.first();
  if(object){
    object.set('active', true);
    object.set('encouragements', 0);
    object.unset('encouragers');
    await object.save();
    request.object.set('artwork', object);
  }
});

marketplace smart contract:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./node_modules/@openzeppelin/contracts/access/Ownable.sol";
import "./OpenMint.sol";
import "./PaymentGateway.sol";

contract OpenMintMarketplace is Ownable {

  OpenMint private _OpenMint;
  PaymentGateway private _PaymentGateway;
  address payable publisherWallet;

  struct Offer{
    address payable seller;
    address tokenAddress;
    uint256 price;
    uint256 offerId;
    uint256 tokenId;
    bool isSold;
    bool active;
  }

  Offer[] public offers;

  mapping(uint256 => Offer) tokenIdToOffer;

  event artworkAdded(address tokenAddress, address seller, uint256 price, uint256 tokenId, uint256 offerId, bool isSold);
  event artworkSold(address tokenAddress, address buyer, uint256 price, uint256 tokenId, uint256 offerId);
  event priceChanged(address owner, uint256 price, address tokenAddress, uint256 tokenId, uint256 offerId);
  event artworkRemoved(address owner, uint256 tokenId, address tokenAddress);

  constructor(address _OpenMintContractAddress, address _PaymentGatewayAddress, address payable _publisherWallet) {
    _setOpenMintContract(_OpenMintContractAddress);
    _setPaymentGatewayContract(_PaymentGatewayAddress);
    publisherWallet = _publisherWallet;
  }

  function _setPaymentGatewayContract(address _PaymentGatewayAddress) private onlyOwner{
    _PaymentGateway = PaymentGateway(_PaymentGatewayAddress);
  }

  function _setOpenMintContract(address _OpenMintContractAddress) private onlyOwner{
    _OpenMint = OpenMint(_OpenMintContractAddress);
  }

  function setOffer(uint256 price, uint256 tokenId, address tokenAddress) public{
    require(_OpenMint.ownerOf(tokenId) == msg.sender, "Only the owner of the artwork is allowed to do this");
    require(_OpenMint.isApprovedForAll(msg.sender, address(this)) == true, "Not approved to sell");
    require(price >= 1000, "Price must be greater than or equal to 1000 wei");
    require(tokenIdToOffer[tokenId].active == false, "Item is already on sale");

    uint256 offerId = offers.length;

    Offer memory offer = Offer(payable(msg.sender), tokenAddress, price, offerId, tokenId, false, true);

    tokenIdToOffer[tokenId] = offer;

    offers.push(offer);

    emit artworkAdded(address(_OpenMint), msg.sender, price, tokenId, offerId, false);
  }
}

token smart contract:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./node_modules/@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "./node_modules/@openzeppelin/contracts/utils/Counters.sol";

contract OpenMint is ERC721 {
  using Counters for Counters.Counter;
  Counters.Counter private _tokenIds;

  constructor () ERC721("OpenMint", "OM"){}

  struct Artwork{
    uint256 id;
    address payable creator;
    address tokenAddress;
    string uri;
    uint8 royalty;
  }

  mapping(uint256 => Artwork) public Artworks;

  function createArtwork(string memory uri, uint8 royalty) public returns(uint256){
    require(royalty > 0, "Royalty cannot be zero or smaller than zero");
    _tokenIds.increment();
    uint256 newArtworkId = _tokenIds.current();
    _safeMint(payable(msg.sender), newArtworkId);

    Artworks[newArtworkId] = Artwork(newArtworkId, payable(msg.sender), address(this), uri, royalty);

    return newArtworkId;
  }

  function tokenURI(uint256 tokenId) public view override returns (string memory) {
    require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

    return Artworks[tokenId].uri;
  }

  function getRoyalty(uint256 tokenId) external virtual view returns(uint8 royalty){
    require(_exists(tokenId), "ERC721Metadata: Royalty query for nonexistent token");

    return Artworks[tokenId].royalty;
  }

  function getCreator(uint256 tokenId) external virtual view returns(address payable creator){
    require(_exists(tokenId), "ERC721Metadata: Creator query for nonexistent token");

    return payable(Artworks[tokenId].creator);
  }
}

Thank you

what are you doing when you are trying a new server?
what is not working with nitro?

I wanted to record a video to show you what is happening but when I was filming, everyting worked fine, the sync event was saved to database after the first transaction without the need of another transaction after it. I dont know what happened, I just restarted the server on moralis that already was the last version (0.0.335) and its the same server that last night didnt saved the sync event to database. Now everyting works, how bizarre :smiley: