RORK LABJP
RORKMAX — Rork Max generates pure Swift instead of React Native, enabling true native apps across iPhone, iPad, Watch, TV, Vision Pro, and iMessageAPPLE — Rork's 2026 direction has a clear theme of native empowerment across the Apple ecosystemEXPO — Standard builds run on React Native and Expo, so you're left with a real project structure and code you can keep working onFUNDING — Rork recently raised $15M and now sees over 743,000 monthly visits with 85% growthPRICING — Rork is free to start, with paid plans from $25/month and Rork Max at $200/monthCROSS — Rork builds iOS, Android, and web from a single prompt, finished off with a bit of follow-up tweakingRORKMAX — Rork Max generates pure Swift instead of React Native, enabling true native apps across iPhone, iPad, Watch, TV, Vision Pro, and iMessageAPPLE — Rork's 2026 direction has a clear theme of native empowerment across the Apple ecosystemEXPO — Standard builds run on React Native and Expo, so you're left with a real project structure and code you can keep working onFUNDING — Rork recently raised $15M and now sees over 743,000 monthly visits with 85% growthPRICING — Rork is free to start, with paid plans from $25/month and Rork Max at $200/monthCROSS — Rork builds iOS, Android, and web from a single prompt, finished off with a bit of follow-up tweaking
Articles/Business
Business/2026-05-21Advanced

Putting AdMob Bidding into Production for a Rork App — Five Networks Bidding in Parallel, eCPM Trends, and Daily Operations

I moved the AdMob mediation layer of my Rork-generated apps from waterfall to bidding, with five ad networks bidding in parallel. Here are my real-world numbers after three weeks of production, the SDK pitfalls, and how I delegate daily monitoring to Claude in Chrome.

AdMob69Bidding2Mediation7Rork504eCPM4Indie Development20

Premium Article

The morning I opened the AdMob dashboard and saw the bidding acceptance rate sitting near 100% across the day, I finally felt that the migration work was behind me. The Rork-generated apps I run had been moving from waterfall mediation to bidding for the past three weeks, and that day was the first one where the numbers looked stable.

I have been shipping mobile apps as an indie developer since 2014. Among everything that has shifted around AdMob, the move from waterfall (call networks in sequence) to bidding (have them bid in parallel) is one of the most meaningful changes for solo operators. On the surface it looks like a single checkbox in the AdMob console, but actually running it in production with several networks side by side took quite a bit of tuning across SDK setup, console configuration, and daily monitoring.

In this post I'm sharing the implementation notes from migrating six wallpaper apps to bidding in parallel. The combined catalog has crossed 50 million downloads over the years, so the numbers below reflect real production traffic, not test environments. I'll cover the integration code I changed on top of the Rork-generated baseline, the three pitfalls that cost me the most time, the eCPM and fill rate shifts I measured against the prior waterfall configuration, and the daily monitoring loop I now run through Claude in Chrome.

Why I Moved off Waterfall — The Ceiling I Could Feel but Not Measure

With waterfall, AdMob queries networks in order of their declared eCPM floor. If I set AppLovin's floor at $2.00 and Unity Ads at $1.50, requests go to AppLovin first and fall through to Unity Ads only when AppLovin doesn't fill. It is a clean mental model, but in my apps it had two limits I kept bumping into.

The first one was that floor values are static, which means they cannot absorb variability across currency, hour of day, and audience composition. AppLovin tends to dominate during Japanese hours; Meta Audience Network shows up stronger during overseas hours. Watching the dashboards I could see the patterns, but adjusting floor values by hand to chase them is not realistic when you have six apps to maintain.

The second one was that unfilled-impression opportunity cost is hard to see. In the waterfall logs you can see "AppLovin didn't fill, so the request went to network 2," but you can't see "if all five networks had bid in parallel, what eCPM would the auction have produced?" Bidding shows you that number every time, because the auction actually happens.

In a bidding setup, AdMob sends a parallel bid request to all participating networks and instantly picks the highest bid that arrives inside the time window. The mechanism removes both limits above. Google has been steering publishers toward bidding in their docs as well, and the case for it is especially strong when you have multiple SDKs co-resident in the same app.

The final shape I landed on is a hybrid: one or two networks stay on the waterfall (because their adapter doesn't support bidding yet), and the five networks that do support bidding compete in parallel.

Separating the Code You Leave Alone from the Code You Touch

A Rork-generated app comes with a reasonable AdMob initialization scaffold. In my wallpaper apps I keep that initialization centralized in App.tsx, and I let all the mediation SDKs load as AdMob adapters rather than as direct SDKs. This keeps the code footprint small and matches what bidding wants.

I use Google's official react-native-google-mobile-ads package rather than the older Firebase wrapper. Bidding has strict requirements around SDK and adapter versions — get them wrong, and bidding will appear to be enabled in the console but never actually fill an impression.

# package.json dependencies
"react-native-google-mobile-ads": "^14.7.0",
"@react-native-async-storage/async-storage": "^1.23.1",

Adapters are picked up through EAS Build natively. In app.json I declare them like this:

{
  "plugins": [
    [
      "react-native-google-mobile-ads",
      {
        "androidAppId": "ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX",
        "iosAppId": "ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX",
        "userTrackingUsageDescription": "Used to measure ad performance for the apps you enjoy.",
        "skAdNetworkItems": [
          "cstr6suwn9.skadnetwork",
          "4fzdc2evr5.skadnetwork",
          "ydx93a7ass.skadnetwork"
        ]
      }
    ]
  ]
}

Every network publishes the SKAdNetwork IDs it needs declared in Info.plist. AppLovin, Unity Ads, Pangle, Liftoff, and Meta Audience Network each have their own list, and I learned to enumerate all of them in skAdNetworkItems. Miss one, and on iOS you can see impressions in the console but the attribution silently breaks, which means the eCPM reports do not reflect actual revenue several days later.

The Rork-generated code itself I leave essentially intact. The three additions I make are: an initialization hook, environment-variable-based ad unit IDs, and an adjustment to where the App Tracking Transparency (ATT) prompt sits in the launch sequence.

// hooks/useAdMobInit.ts
import { useEffect } from "react";
import { Platform } from "react-native";
import mobileAds, { MaxAdContentRating } from "react-native-google-mobile-ads";
import { request, PERMISSIONS, RESULTS } from "react-native-permissions";
 
export const useAdMobInit = () => {
  useEffect(() => {
    const init = async () => {
      if (Platform.OS === "ios") {
        // Resolve ATT before initializing AdMob
        await request(PERMISSIONS.IOS.APP_TRACKING_TRANSPARENCY);
      }
      await mobileAds()
        .setRequestConfiguration({
          maxAdContentRating: MaxAdContentRating.PG,
          tagForChildDirectedTreatment: false,
          tagForUnderAgeOfConsent: false,
        })
        .then(() => mobileAds().initialize());
    };
    void init();
  }, []);
};

The detail that matters is resolving the ATT dialog before AdMob initializes. Reversing the order causes personalized ads to drop off on iOS 14.5+ devices and, in my measurements, takes 20–25% off the bidding eCPM. The same principle applied under waterfall, but the impact is larger now that bidding amplifies competition for ATT-authorized impressions.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Concrete SDK integration steps for AdMob Bidding alongside an existing waterfall setup, with the gotchas I hit on iOS and Android
Three weeks of measured eCPM, fill rate, and latency numbers across five networks (AppLovin / Meta Audience Network / Unity Ads / Pangle / Liftoff)
How I delegate the morning dashboard rounds to Claude in Chrome, including the prompt structure and the alert rules I rely on
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Business2026-07-05
When Your AdMob Earnings Suddenly Get Deducted: Preventing Invalid Traffic as a Solo Developer
Invalid traffic deductions in AdMob are unsettling because the cause is rarely obvious. From the perspective of running several apps solo, here is a minimal setup that prevents the most common accidents, plus how to respond when a deduction actually happens.
Business2026-06-04
Expanding AdMob bidding demand without adding SDKs — what applying to 11 server-side partners taught me about 'enabled ≠ serving'
A working log of actually adding SDK-free, server-side bidding partners to AdMob's bidding sources: the difference between doc-type and form-type sign-up flows, how reCAPTCHA behaves, and the trap that 'partnership enabled' does not mean 'eligible to serve', told from a solo developer's point of view.
Business2026-05-30
Two Weeks After Adding Pangle and Mintegral to My AdMob Waterfall — Notes on eCPM and Fill Rate
A record from a wallpaper app with over 50 million downloads: I added Pangle and Mintegral to my AdMob mediation, then compared two weeks of eCPM and fill-rate data. Bidding-and-waterfall coexistence, the effective-revenue breakdown, region-based groups, and a daily monitoring script — kept in a form you can actually operate.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →