This requires indexing the blockchain. This is fairly simple using Moralis APIs. https://docs.moralis.io/web3-data-api/evm/how-to-get-nft-owners-by-an-address
Alternative, you can do this using ethers.js:
const { ethers } = require('ethers');
const networkUrl = 'https://eth-mainnet.your-moralis-server.com/APIKEY';
const provider = new ethers.providers.JsonRpcProvider(networkUrl);
const contractAddress = '0x...'; // Replace with the actual contract address
const abi = [...]; // Replace with the ABI of the ERC721 or ERC1155 contract
const contract = new ethers.Contract(contractAddress, abi, provider);
For ERC721:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/ffceb3cd988874369806139ae9e59d2e2a93daec/contracts/token/ERC721/ERC721.sol#L60
const ownerAddress = '0x...'; // Replace with the owner's address
const balance = await contract.balanceOf(ownerAddress);
For ERC1155:
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/ffceb3cd988874369806139ae9e59d2e2a93daec/contracts/token/ERC1155/ERC1155.sol#L78
const ownerAddress = '0x...'; // Replace with the owner's address
const tokenIds = [1, 2, 3]; // Replace with the desired token IDs
const balances = await contract.balanceOfBatch([ownerAddress], tokenIds);
The balance or balances variable will contain the number of NFTs owned by the address. You can then loop through the token IDs.