DEV Community

Cover image for Technical Post-Mortem: Debugging AdMob Impression Leaks in an Expo/Firebase Mobile App
Jane49-cloud
Jane49-cloud

Posted on

Technical Post-Mortem: Debugging AdMob Impression Leaks in an Expo/Firebase Mobile App

As a mobile developer, shipping an app to production is only half the battle. The real complications begin when analyzing live telemetry and monetization data.

I recently launched a personal intermittent fasting tracker built on React Native (Expo) and Firebase called LifeFast. The app uses an ad-supported model to offset background hosting and real-time community feed sync costs.

After reviewing my first week of live AdMob metrics, I noticed a major bottleneck in the rendering lifecycle: a severe disconnect between Ad Requests and Actual Impressions.

The Data Log
Total Requests: 1.11K (Strong API connectivity)

Match Rate: 70.03% (AdMob is successfully returning inventory)

Impressions: 345 (The bottleneck)

Out of ~770 successfully returned ad units, less than half are registering as viewed by users.

Breakdown by Ad Unit Lifecycle

  1. Interstitials (eCPM: €1.50 | 44 Impressions) The eCPM here is the highest, but the volume is low.

The Root Cause: The layout logic was attempting to load and display the interstitial simultaneously during screen state transitions. If the user navigates faster than the network request completes, the ad is dropped, resulting in a matched request but zero impressions.

The Fix: Migrating to a pre-loading architecture using ad.load() immediately upon component mount, caching the unit globally, and only executing ad.show() during natural UX breakpoints.

  1. App Open Ads (eCPM: €1.46 | 139 Impressions) The Root Cause: The current trigger relies heavily on a cold app start. If a user backgrounds the app to check a message and resumes their fast tracking, the lifecycle event isn't consistently capturing the background-to-foreground transition.

The Fix: Listening directly to React Native's AppState changes to ensure the ad logic evaluates state changes from background -> active.

  1. Banner Ads (eCPM: €0.21 | 162 Impressions) The Root Cause: Standard fixed-size banners are occasionally clipping outside the viewport on varying Android aspect ratios, firing the request script but failing the viewability requirements.

The Fix: Deprecating fixed widths in favor of Adaptive Banners that dynamically calculate the screen width container before requesting the asset.

Marketing an Independent Project on a $0 Budget
The other engineering challenge is organic discovery. Traditional social platforms have highly aggressive automated spam filters that auto-flag direct Play Store links, making standard community outreach unviable.

To bypass this without a marketing budget, I am currently implementing a code-driven viral loop using react-native-share to let users natively export progress milestones to their personal networks, shifting the acquisition logic directly into the application codebase.

For context on the layout implementation or to see how the live UI handles these ad placements, the application is live on the Google Play Store under LifeFast.

If anyone has optimized the match-to-impression ratio inside an Expo ecosystem, I'd be interested in comparing lifecycle architectures in the comments.

Top comments (0)