useMoralisSubscription() being triggered twice

Hey all, I am using react-moralis and the useMoralisSubscription hook to listen to sync’d events in my moralis database server. Everything works perfectly. The server listens for events from my smart contract getting emitted and then my dapp instantly updates when a new event is added to the database.

My problem is that for some reason this gets triggered twice per event entry. After about 2 minutes my useMoralisSubscription hook is triggered again despite no new entry being added to the database.

below is the code.

useMoralisSubscription('SupplyChanges', (q) => q.limit(1), [], {

         onUpdate: (data) => {

            console.log('SERVER EVENT TRIGGERED!');

            initializeDataFromServer(data);

        },

    });

Can we see the full component?

The rest of the code is mostly frontend dapp related and is too long to post, plus isn’t really related to this issue. Below is full code that involves the database.

const { data, error, isLoading } = useMoralisQuery(

        'SupplyChanges',

        (query) => query.limit(1),

        [],

        {

            live: true,

        },

    );

    // onUpdate is the one that works.  onCreate only works if you manually add an entry to the database yourself thru the admin panel.

    useMoralisSubscription('SupplyChanges', (q) => q.limit(1), [], {

        onUpdate: (data) => {

            console.log('SERVER EVENT TRIGGERED!');

            initializeDataFromServer(data);

        },

    });

So it happens every time after 2 minutes? Something must be updating SupplyChanges in some way to trigger it.

What does logging the data in the onUpdate look like (both times)? Have a look at any differences e.g. in attributes.

1 Like

Thanks for the suggestion. After logging the actual data I’ve figured out the issue. It seems there is a confirmed boolean value for every entry in the database. This is false when the event fires but after 3 minutes it confirms to true causing an update of that value and thus re-triggering my useSubscription hook on my frontend.

What exactly is this confirmed property? I’m assuming it’s waiting for a confirmation of the tx that logged the event however why is it false when a new event is added into the database? Maybe it’s waiting for 2 confirmations before turning the boolean to true but either way this is an issue now.

The whole reason I am using the onUpdate vs the onCreate method for handling the subscription is because onCreate doesn’t work with sync events but now it’s firing anytime some arbitrary value updates which is causing an issue.

The obvious thing to do is to just write a condition to only run logic in the callback if that confirmed boolean is false but since I’m likely to deploy in bsc and avax that may not even trigger properly/consistently. I dunno.

It is an expected behavior. You can look at the fields and you can differentiate between first trigger and the second one based on the data. On create doesn’t work because it is an update that replaced it.

Confirmed is set after a number of blocks were mined and confirmed that transaction to be sure that it can not be changed by a reorg.

You can use also afterSave triggers and set a new flag in a new column in that table.

How come onCreate doesn’t work when new entries are created via sync events? OnCreate works when I manually add a new entry via the panel but not for sync events.

What does afterSave do exactly and when does it trigger? After something is first saved? To be clear I need the first trigger to set off some logic in my frontend which is time sensitive so I cannot wait for the full tx confirmation to trigger the callback again in order to run that logic.

Or maybe I should wait for a full confirmation just to make sure it can’t reorganize?

After save triggers on every save. You can use a flag to know when it was the first save/update.

On create doesn’t work because of the way the data is added with upsert in the database on sync, and an update will trigger when the events are synced in the database.

1 Like

Thanks, I’ll try this out.

I used q => q.equalTo("confirmed", true), so that the trigger only happens when the transaction is confirmed. It works so far.

1 Like