ANTIGRAVITY LABJP
Articles/App Development
App Development/2026-06-23Advanced

The Review Prompt Fired but Nothing Appeared — Designing Around Play In-App Review's Quota and No-Show Guarantee

Play In-App Review's launchReviewFlow can succeed without ever showing a dialog. This walks through the three traps — quota, no display guarantee, and silent testing — and the engagement-based trigger design that fires at the right moment without colliding with ads, with steps to have Antigravity implement it.

in-app-reviewAndroid16monetization29Kotlin4Antigravity261

Premium Article

I still remember the day I wired Play's In-App Review into one of my calming wallpaper apps. I called launchReviewFlow, the addOnCompleteListener came back successful, the log printed "review flow finished" — and yet the star-rating dialog never appeared on screen. Not once.

I swapped test devices, swapped accounts, and tried dozens of times with the same result. The code looked like it was working, but the one thing I cared about stayed silent. As an indie developer who has been shipping apps for years, even I spent the better part of a day convinced my own implementation was broken, hunting for the bug.

The short version: what was broken wasn't the implementation, it was my assumption. Play In-App Review is not a "call it and it shows" API. Google decides whether to display it, and that decision is invisible to you. This article is the trigger design that only becomes correct once you put "no display guarantee" at the center, written up alongside the implementation code.

The contract: a successful callback is not a display guarantee

The first mental shift is that completion of launchReviewFlow does not mean "the dialog was shown." By design, there is no API that tells your app whether the review flow was actually displayed. The completion listener reports only that the flow finished — it cannot distinguish between shown, suppressed by quota, or already reviewed.

// ❌ The common misread — assuming "completed" means "shown"
manager.launchReviewFlow(activity, reviewInfo)
    .addOnCompleteListener { task ->
        // Even with task.isSuccessful == true, the dialog may never have appeared
        // Do NOT set a "reviewed" flag here
        markReviewedAndNeverAskAgain()   // ← this is what breeds the silence
    }

Half of the day I burned came from exactly this. Because I was persisting a "don't ask again" flag in the completion callback, a single run of the flow put the app into a state where it would never fire again — a trap I had built myself. The correct move is to do nothing meaningful in the callback (or, at most, advance an internal cooldown). The starting point is to stop trying to determine, from your side, whether a review happened.

What you want to knowDoes the API return it?Design to adopt
Was the dialog shown?NoDon't make UX depend on display
Did the user leave a rating?NoNo post-rating rewards or branching
Was it suppressed by quota?No (returns success)Cooldown, ready to re-fire later
Did the flow finish?YesUse only to resume navigation

Quota: the invisible wall

The next wall is quota. In-App Review caps how often the review prompt can be offered to the same user. Call launchReviewFlow repeatedly in a short window and the excess calls are quietly ignored — no dialog. And as above, that suppression is invisible from the callback. It comes back as success.

This is genuinely nasty for an indie developer. During testing you launch the app over and over and keep satisfying your review conditions. The result: your own development account hits the quota first, producing exactly the initial symptom — "I implemented it and it won't show."

The design implication is clear: throttle firing deliberately on your side rather than leaning on the API's limit. In my calming apps, the review prompt only fires when "enough time has passed across sessions" and "a satisfaction signal is present." The API quota is just the last safety net; ideally your own trigger policy has already narrowed things down well before it.

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
Understand the real contract — a successful launchReviewFlow does not mean a dialog was shown — and build code that never makes UX depend on that callback
Ship a review prompt that actually works in production by avoiding the three traps: quota, ReviewInfo lifetime, and silent no-ops in test builds
Port an engagement-based trigger that fires only at the peak of satisfaction and yields to ads and paywalls instead of stacking requests
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

Antigravity 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

App Dev2026-04-02
Building Flutter + Kotlin Apps at Lightning Speed with Antigravity
A practical guide to using Google Antigravity for Flutter and Kotlin mobile app development. Covers AgentKit 2.0-powered UI generation, Dart code completion, Android native integrations, and App Store/Play Store deployment.
App Dev2026-06-21
A Few Low-Density Phones Lost Their Bundled Wallpaper — The drawable vs nodpi Boundary in Play's Density Splits
App Bundle density splits will happily split images that should never be split, dropping a static resource on one density bucket only. Here is how I reproduced it with bundletool and fixed it by moving to drawable-nodpi or disabling density split — with the decision criteria.
App Dev2026-05-25
One Month Splitting Antigravity's Inline Edit and Agent Mode Across Four Wallpaper Apps
A month of notes from running Antigravity's Inline Edit and Agent Mode across four production wallpaper apps — with real counts, the decision rule I wrote into AGENTS.md, a one-pass dSYM fix, and how credit cost factors in.
📚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 →