Help with error connecting Moralis and MongoDB

Hi guys, I was following the tutorial “Connect to a Database with Web3 Authentication | MongoDB, NextJS and Moralis”. However, the information sent to MongoDB, in this tutorial, is from the “signin” page, and I would like to, instead of using the information from that page, send to the database the information generated in the “protected” page as “Nftlist”. Because I am creating my Dapp using the nft-gating template, and there is a “protected” page. I would like to get the user information generated on that page(protected page) to send to my database.

I am trying to do it this way:

export async function getServerSideProps(context) {
    const session = await getSession(context);

    if (!session) {
        return {
            redirect: {
                destination: '/signin',
                permanent: false,
            },
        };
    }

    await Moralis.start({ apiKey: process.env.MORALIS_API_KEY });

    const nftList = await Moralis.EvmApi.account.getNFTsForContract({
        address: session.user.address,
        tokenAddress: ‘xxxxx’,
        chain: 1
    });

    await connectDB();
    const MongoUser = await Users.findOne({owner_of: owner_of}, {token_id: token_id}, {block_number: block_number}, {token_address: token_address}, {token_hash: token_hash})

    if(!MongoUser){
    
      const newUser = new Users({
        profileId: profileId
      })
      await newUser.save();

    }

    return {
        props: {
            message:
                // if user has at least one NFT he will get protected content
                nftList.raw.total > 0 ? 'Nice! You have our NFT' : "Sorry, you don't have our NFT",
            nftList: nftList.raw.result,
        },
    };
}

export default Protected;

But I am getting this error:

And I don’t know what I am doing wrong since the constant Nftlist has this following attributes:

Could someone help me with this? How can I send these attributes generated by this “Nftlist” to my database when the user enters this page?

at a first look it looks like that variable name named owner_of is not defined

But how can I define if it is inside nftList?

Note: I tried something simpler sending to the database the whole information inside nftList like this:

and it sends nothing… only an “ObjectId” that I think is automatically generate on the database…

You need to get it from nftList, same for all the other variables that don’t seem to be defined like token_id and block_number. If you use a variable it needs to come from somewhere, this isn’t Moralis specific.

E.g. you could use:

nftList.raw.result[0].owner_of

To get the owner_of from the first result.

Thanks glad, by declaring the constants this way I succeeded, but only partially, because it does not work for all the parameters from the nftList. Since when I try to do it for the “token_id” I get the following error:

And thinking about the “token_id”, how would it be possible to send to the database a user that has an token with id different than 0 from the same Smart Contract, if we are using a nftList.raw.result [0] .token_id in this case?

Looks like you haven’t changed the object property names used in findOne. Or have you created a token_id above?

Also based on the error it looks like you’re not using the parameters in findOne correctly, you can read the docs.

I did create a token_id above using the same code you sent me before:

const token_id = nftList.raw.result.token_id

And I did the same thing for other information (owner_of, token_address,token_harsh and block_number), but the only one that returns with an error is the token_id… Do you think there is a problem with not informing the token id in between brackets?

Do you also know if its possible to get the information without telling the token_id in between brackets?

how can I get the information without having to inform the token id, like in this example:

const token_address = nftList.raw.result[0].token_address

this syntax seems strange, it is expected to have all those parameters sent this way?

Actually, I just followed the tutorial but instead of using the parameters on the video, I was trying to stablish this ones.

And without “token_id”, it works just fine, the page loads and the database upgrade with all the information from the user. But the problems are that I do need to get the token id to know which token the user has and I need to get the users informations for any token ( if the person has token 0,1,2,3…). But, using the code suggested I could only get 1 of the tokens info and I was not able to get “token_id”.

I don’t know if that is the expected syntax . What is the syntax without token id that works fine?

This is the code that it is working (without the “token_id” and only getting the values for the id token 0):

export async function getServerSideProps(context) {
    const session = await getSession(context);

    if (!session) {
        return {
            redirect: {
                destination: '/signin',
                permanent: false,
            },
        };
    }

    await Moralis.start({ apiKey: process.env.MORALIS_API_KEY });

    const nftList = await Moralis.EvmApi.account.getNFTsForContract({
        address: session.user.address,
        tokenAddress: ‘xxxxx’,
        chain: 1
    });

    const owner_of = nftList.raw.result[0].owner_of
    const block_number = nftList.raw.result[0].block_number
    const token_address = nftList.raw.result[0].token_address
    const token_hash = nftList.raw.result[0].token_hash

    await connectDB();
    const MongoUser = await Users.findOne({owner_of: owner_of}, {block_number: block_number}, {token_address: token_address}, {token_hash: token_hash})

    if(!MongoUser){
    
      const newUser = new Users({
        owner_of: owner_of,
        block_number: block_number,
        token_address: token_address,
        token_hash: token_hash,
      })
      await newUser.save();

    }

    return {
        props: {
            message:
                // if user has at least one NFT he will get protected content
                nftList.raw.total > 0 ? 'Nice! You have our NFT' : "Sorry, you don't have our NFT",
            nftList: nftList.raw.result,
        },
    };
}

export default Protected;

and you have token_id column in user table and it has values for all the rows?

Yes I have everything coded the right way.

On userSchema.js:

import mongoose from "mongoose";

const userSchema = new mongoose.Schema(
  {
    owner_of: {
      type: String,
    },
    token_id: {
      type: String,
    },
    token_address: {
      type: String,
    },
    block_number: {
      type: String,
    },
  },
  { timestamps: true }
);

let Users = mongoose.models.users || mongoose.model("users", userSchema);

export default Users;

And on the protected page:

   const nftList = await Moralis.EvmApi.account.getNFTsForContract({
        address: session.user.address,
        tokenAddress: 'xxxxx',
        chain: 5
    });

    const owner_of = nftList.raw.result[0].owner_of
    const token_id = nftList.raw.result.token_id
    const block_number = nftList.raw.result[0].block_number
    const token_address = nftList.raw.result[0].token_address
    
    await connectDB();
    const MongoUser = await Users.findOne(
        {owner_of: owner_of}, 
        {token_id: token_id},
        {token_address: token_address},
        {block_number: block_number},
        )

    if(!MongoUser){
    
      const newUser = new Users({
        owner_of: owner_of,
        token_id: token_id,
        token_address: token_address,
        block_number: block_number,
      })
      await newUser.save();

    }

You changed the User table to have only those columns?

You can also install parse dashboard to manage the tables

This line doesn’t have that [0]

Yes, because my idea would be to identify the id of the token and not just identify the token with id 0. When I write [0], I am establishing that only the token with id 0 will be stored, right?

No, if you look at this code one like doesn’t get the data from the same result object at index 0

I tried to insert [0]:

    const owner_of = nftList.raw.result[0].owner_of
    const token_id = nftList.raw.result[0].token_id
    const block_number = nftList.raw.result[0].block_number
    const token_address = nftList.raw.result[0].token_address

but got the same error:

now, it looks like the syntax is not the right one, with so many parameters to that findOne function

try to create a single object with all the parameters and send it as a parameter to findOne and not 3 different parameters to findOne

How could I do this? What is the best way?