Built NextJS App, does not get user data from useNativeBalance react hook after a refresh, but works fine in dev

So I have this weird issue in my app, where after the first time someone connects with Metamask, it all works just fine, but once the user refreshes/disconects etc, anything after the first sign in, I can no longer get his wallet address or tokens balances.

It is important to note that this only happens after the app is being BUILT and served (both locally and on vercel, both have that issue!). No such issues when its being run in dev mode.

The only way for me to again get information about currencies and things like that is for the user to disconnect (from Metamask!) and reconnect, and then it repeats, on the first sign in I’ll get them and then I won’t.

Here is a minimal code to reproduce it:

import { useMoralis, useNativeBalance, useERC20Balances } from 'react-moralis'

import { useEffect } from 'react'

export default function Home() {

  const {
    authenticate,
    enableWeb3,
    isAuthenticated,
    logout,
    user,
    account,
  } = useMoralis()

  const { data: nativeBalance } = useNativeBalance()
  const { data: tokensBalance } = useERC20Balances()

  console.log(user?.attributes?.ethAddress)  
  console.log('account', account)            
  console.log('nativeBalance', nativeBalance)
  console.log('tokensBalance', tokensBalance)

  useEffect(() => {
    const authAndEnable = async () => {
      try {
        await authenticate()
        await enableWeb3()
      } catch (e) {
        console.log(e)
      }
    }

    if (isAuthenticated) {
      authAndEnable()
    }

  }, [])

  return (
    <main>
      <button onClick={isAuthenticated ? logout : authenticate}>
        {isAuthenticated ? 'Disconnect' : 'Connect'}
      </button>
    </main>
  )
}

This code goes into pagse/index.js in a brand new next app, created with:
create-next-app .

The only packages installed are:

npm i moralis react-moralis @walletconnect/web3-provider

npm run build && npm run start and there you have it.

I have just installed it, so I should be with the latest versions of the packages:

  "dependencies": {
    "@walletconnect/web3-provider": "^1.7.0",
    "moralis": "0.0.176",
    "next": "12.0.7",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-moralis": "^0.3.11"
  },

Here’s a short video that I made to show it: https://youtu.be/WKzyMkVEMNQ

Why it would authenticate again if is authenticated?

Maybe you need to check if everything is loaded/enabled before getting the balance.

Whether it does authenticate again or not is irrelevant, it still needs to get enabled so that it connects to metamask. That is not the issue, and yes I have just tried now with removing the authenticate() method inside and leaving only the enable.

What is that “everything”?

Also I just tried adding another useEffect to track for changes in nativeBalance, tokensBalance and account and log their values if they do get changed:

  useEffect(() => {
    console.log(user?.attributes?.ethAddress)   
    console.log('account', account)             
    console.log('nativeBalance', nativeBalance) 
    console.log('tokensBalance', tokensBalance) 
  }, [user, account, nativeBalance, tokensBalance])

Also no effect, they are still null.

Please, keep in mind this, as I have already mentioned, this is only after the app is built, there are no problems when running in dev mode.

you may need to use these hooks

Option	Description
Moralis	The global Moralis instance (same as the global Moralis object)
isInitialized	A boolean, indicating if Moralis has been initialized
isInitializing	A boolean, indicating if Moralis is currently initializing

you can also search on forum for others that had the same problem, I’m not really expert in react

Thanks, I appreciate it, I just checked these two variables and added them as conditions and in the dependency array of useEffect:

useEffect(() => {
    if(isInitialized && !isInitializing){  
      console.log('initilized',isInitialized)
      console.log('initializing', isInitializing)
      console.log(user?.attributes?.ethAddress)  
      console.log('account', account)            
      console.log('nativeBalance', nativeBalance)
      console.log('tokensBalance', tokensBalance)
    }

  }, [isInitialized, isInitializing, user, account, nativeBalance, tokensBalance])

Again no change, it behaves the same way.

this code executes?

I think that you can fetch the user info somehow

It behaves exactly as I show in the video, once the user connects, he needs to disconnect from metamask itself in order for me to retrieve his information, and I can do that only on first connect, then I lose it. Yes these two variables are working, but they are not helping.

after refresh, the problem is that you are no longer connected to MetaMask? like you need to run enableWeb3?

Pls watch the video that I have attached to my original post.

It says that I am connected, and it also says that I am authenticated, but I don’t get any information from Metamask, no matter if i disconnect and reconnect (from the button), I only get the currencies information once I disconnect from metamask itself and reconnect. And I get it only the first time.

1 Like

Okay I did a little bit of digging and what ends up happening is that the app is not sending requests to Moralis servers at all:

This is when I first sign in and I retrieve the data, you can see that there are requests for getNativeBalance, getTokensBalance and so on.

And this is when I refresh on the same page as it was on the above screenshot:

As you can see, these requests are not being made at all.

It may not need to do all those requests again, if you want information from MetaMask all you need is web3

Then what do I need Moralis for, if I can’t use its hooks, to get the information I need?

I looked now at the video, for nativeBalance it doesn’t really need metamask to get that info, it will make a request to your Moralis Server, it only needs metamask to know the account eth address at the initial authentication

now you say that it doesn’t even make those calls to get the native balance when it doesn’t work, and it can not show the data if it doesn’t make those calls

the problem seems to be somehow that it doesn’t make those calls on refresh

maybe you need to use some of the variables that it returns:

 return {
    getBalances: fetch,
    data: {
      balance: data?.balance,
      formatted,
    },
    nativeToken,
    error,
    isLoading,
    isFetching,
  };

And I do use them in my real application, the code I shared above is just a minimal example that reproduces the bug, I am using those on my application and I am trying to read them and output them in my interface.

And yes, the problem is that it stops making those calls after the first connecting to Metamask.

maybe you can call this to fetch

or check these variables:

you could also try to call web3api directly: Moralis.Web3.getNFTs broken for avalanche

1 Like

I just tried that and isFetching is true only the first time, it never gets set to true after that, so indeed, the API just does not fetch the data, which leads me to believe that this should be something very easy to fix in the react-moralis api…

In dev mode isFetching always gets set to true before it retrieves the data, when I build the project, it gets set to true just once, after the initial first sign in where it connects to Metamask and tahts it, it never gets set to true after that.

maybe you can force a fetch with that getBalances: fetch,

I just tried using the getBalance and fetchERC20Balances both of which when activated seem to be working now and retrieving the balances and sending the requests, however this still seems like a bug, its working on dev mode, I cant even think of a reason why that wouldnt work normally. And now I need to write logic about fetching… So thanks, at least finally you helped me find a way to get it working.

I am new to all of this in general, but if I have to write custom code for that, or dealing with web3 directly, why do I need Moralis in the first place?