Preheat oven to 400°F (200°C).
Prepare all the ingredients: dice the ham, slice the onions and the mushrooms, and shred the cheese.
In a separate large bowl, whisk the eggs with the heavy cream, salt and pepper. Then stir in the Cheddar and Parmesan cheese. Set aside.
Melt the butter (or olive oil) in an oven-safe skillet (or Dutch oven) over medium-high heat. Add the onions and sauté until soft and translucent, around 8-10 minutes. Then, add the mushrooms and pressed garlic and cook for 3-4 minutes until all moisture evaporates, otherwise the frittata will be watery.
Then, add the diced ham and cook for another 2-3 minutes until warmed through and a bit caramelized around the edges. Now, add the spinach and cook for an additional minute until wilted.
Pour the whisked eggs over the mushroom and ham mixture. Cook on medium heat until the eggs start to bubble, then lower the heat to medium-low. Using a silicone spatula keep pulling the eggs from the sides to the center. You are basically pulling the eggs that are already scrambled and letting the uncooked egg fill in that space. This will fluff up the frittata giving it more height. Once the eggs start to set around the edges and on the bottom of the pan, it's time to transfer the skillet to the oven. At this point, I like to arrange a few sliced mushrooms on top and drizzle them with oil, so the frittata looks nicer once baked.
Transfer the frittata to the preheated oven and bake uncovered for another 10-12 minutes, until the center looks just slightly jiggly. Keep in mind that the eggs will continue to slightly cook from the residual heat of the pan after removing it from the oven. The frittata should be nice and golden, but still have a tender and creamy texture.
Once ready, remove the frittata from the oven and let rest for 5-7 minutes.
After the frittata has set, slice and sprinkle with fresh parsley, green onions, chives or smoked paprika (optional). Enjoy!