- Google Play
- Ratings
- Android
Google Play In-App Review API: how to ask for ratings in Android, React Native and Flutter apps
Add the Google Play In-App Review API to your app: Kotlin, React Native and Flutter code, when to ask, quotas, testing, and why the dialog is not showing.
AppRanker team13 min read

On this page
The Google Play In-App Review API lets an Android app ask for a star rating and a short review without sending the user to the Play Store. The user sees a native Google Play card on top of your app, taps a rating, optionally writes a comment and goes straight back to what they were doing. It is the single best way to get a steady flow of fresh ratings on Google Play, and it is also the source of one of the most-viewed Android questions on Stack Overflow: "Play Core In-App Review API not showing the Review Activity".
This guide covers why fresh ratings matter for your listing, Google's rules for when you may ask, working code for Kotlin, React Native, Expo and Flutter, how to test the flow before release, and a troubleshooting table for when the dialog does not appear. Everything is taken from Google's documentation and the libraries' own docs, linked as we go.
Key takeaways
- The API works on Android 5.0 (API 21) and later and on ChromeOS, on devices with the Google Play Store installed. The current library is
com.google.android.play:review:2.0.2.- Google enforces a time-bound quota. Calling the flow more than once in a short period (Google's example is "less than a month") may show nothing, so never put it behind a button.
- Do not ask "Do you like the app?" or "Would you rate this app 5 stars?" before or during the card. Do not offer a reward for a rating: Google Play's policy prohibits incentivized ratings.
- The API never tells you whether the user rated or even saw the card. Always continue your normal flow when it completes.
- Test on an internal test track (no quota) or with internal app sharing (fast, but the submit button is disabled). Most "not showing" reports come from testing the wrong way.
Why the in-app review flow matters for your Google Play listing
Your rating is one of the first things a person sees on your listing and next to your app in search results, and it is no longer a lifetime average. Google's ratings and reviews help page says: "Currently, the rating that users see on Google Play is weighted towards more recent ratings to reflect changes and updates that you make to your app."
That has two consequences. A rough patch a year ago fades as new ratings arrive, which is why we argued in our post on resetting your App Store rating that on Android the fix is to ship the fix and then collect fresh ratings. And if you stop collecting ratings, a handful of recent one-star reviews from frustrated users can drag your score down, because happy users rarely go to the store on their own to say so.
Ratings and review text now also feed Google's AI surfaces. Ask Play's new app comparisons summarize "your store listing and user reviews", which we covered in how to get your app recommended in Gemini and Ask Play. A steady stream of specific, recent reviews gives those summaries something accurate to say.
How the Google Play In-App Review API works
The flow has two calls:
requestReviewFlow()asks Google Play for aReviewInfoobject. Do this shortly before you plan to show the card.launchReviewFlow(activity, reviewInfo)shows the card. When the task completes, carry on with your app.
Google's overview lists the supported devices: "Android devices (phones, tablets, and TVs with Google TV) running Android 5.0 (API level 21) or higher that have the Google Play Store installed" and "ChromeOS devices that have the Google Play Store installed." The user can "rate your app using the 1 to 5 star system and to add an optional comment. Once submitted, the review is sent to the Play Store and eventually displayed."
What you may and may not do
Google's design rules are short and strict:
- Trigger the flow "after a user has experienced enough of your app or game to provide useful feedback."
- "Don't prompt the user excessively for a review."
- Your app "shouldn't ask the user any questions before or while presenting the rating button or card", including opinion questions such as "Do you like the app?" and predictive ones such as "Would you rate this app 5 stars".
- Show the card as it is: no changes to size, opacity or shape, no overlays, and never remove it programmatically.
The no-questions rule rules out the classic "Enjoying the app? Yes / No" gate that sends happy users to the store and unhappy ones to a feedback form. Separately, Google Play's User Ratings, Reviews, and Installs policy says: "We prohibit any manipulation of ratings, reviews, or install counts. This includes incentivizing feedback, using forced pop-ups, or paying for fake reviews." No coins, no unlocks, no discounts in exchange for stars.
The quota
Google "enforces a time-bound quota on how often a user can be shown the review dialog." Its example: calling launchReviewFlow "more than once during a short period of time (for example, less than a month) might not always display a dialog." The exact value "is an implementation detail" and can change without notice.
This is why Google says "you should not have a call-to-action option (such as a button) to trigger the API": a user who already hit the quota taps your button and nothing happens. For a permanent "Rate us" item in your settings menu, open the Play Store listing instead (shown below).

The review card appears on top of your app, so pick a moment when the user has just finished something, not one where they are mid-task. Photo: Zain Ali / Pexels
Pick the right moment to ask
Because you get roughly one shot per user per period, the moment matters more than the code. Good moments share three traits: the user just succeeded at something, they are between tasks, and they have used the app enough to have an opinion.
| App type | A good moment | A bad moment |
|---|---|---|
| Productivity | After the third exported document or completed project | On first launch, or while the user is typing |
| Fitness | After a finished workout, on the summary screen | Mid-workout, or after a missed goal |
| Game | After winning a level, before the next one starts | During gameplay, or right after a loss |
| Utility | After the tool has done its job several times | Right after an error or a crash recovery |
A simple eligibility rule you control keeps the API calls rare. This is our own example logic, not something Google prescribes; tune the numbers to your app:
// Ask only after a few real successes, a few days of use, and not too often.
fun shouldAskForReview(prefs: SharedPreferences, now: Long = System.currentTimeMillis()): Boolean {
val successes = prefs.getInt("core_action_count", 0)
val firstOpen = prefs.getLong("first_open_at", now)
val lastAsked = prefs.getLong("review_last_asked_at", 0L)
val day = 24 * 60 * 60 * 1000L
return successes >= 3 &&
now - firstOpen >= 3 * day &&
now - lastAsked >= 90 * day
}
Record review_last_asked_at when you call launchReviewFlow, not when the user rates, because you cannot know whether they did.
Add the In-App Review API in Kotlin
Add the dependency from Google's Maven repository, as shown in the Kotlin and Java integration guide:
// build.gradle.kts (app module)
dependencies {
implementation("com.google.android.play:review:2.0.2")
// Kotlin extensions for the review library:
implementation("com.google.android.play:review-ktx:2.0.2")
}
Then request a ReviewInfo ahead of time and launch the flow at your chosen moment. Google notes that "the ReviewInfo object is only valid for a limited amount of time", so pre-cache it only once you are sure you will launch.
class ReviewPrompter(private val activity: Activity) {
private val manager = ReviewManagerFactory.create(activity)
private var reviewInfo: ReviewInfo? = null
// Call when the user is close to the success moment, e.g. on the last step.
fun prepare() {
manager.requestReviewFlow().addOnCompleteListener { task ->
if (task.isSuccessful) {
reviewInfo = task.result
} else {
val code = (task.exception as? ReviewException)?.errorCode
Log.w("ReviewPrompter", "requestReviewFlow failed: $code")
}
}
}
// Call at the success moment. onDone always runs, whatever happened.
fun launch(onDone: () -> Unit) {
val info = reviewInfo ?: return onDone()
manager.launchReviewFlow(activity, info).addOnCompleteListener {
// The API does not say whether the user reviewed or saw the card.
reviewInfo = null
onDone()
}
}
}
Two rules from Google's guide are built into that code. "If an error occurs during the in-app review flow, do not inform the user or change your app's normal user flow." And "wait until the user has completed the in-app review flow before your app continues its normal user flow (such as advancing to the next level)."
The ReviewErrorCode values you may see in your logs are PLAY_STORE_NOT_FOUND (-1, no Play Store or an unofficial one), INVALID_REQUEST (-2) and INTERNAL_ERROR (-100). Log them; do not show them.
Native C++, Unity and Unreal Engine have their own integration guides, linked from Google's In-App Review overview.
React Native, Expo and Flutter
Expo: expo-store-review
Expo's StoreReview module wraps the same API. Install it with npx expo install expo-store-review. On Android, it uses the ReviewManager API on Android 5 and later.
import * as StoreReview from 'expo-store-review';
export async function maybeAskForReview(eligible: boolean) {
if (!eligible) return;
if (await StoreReview.hasAction()) {
await StoreReview.requestReview();
}
}
Bare React Native: react-native-in-app-review
For apps without Expo modules, the react-native-in-app-review package (version 4.4.2 at the time of writing) calls the Play In-App Review API on Android and the native prompt on iOS. Gate it with the same eligibility check as above.
Flutter: in_app_review
The in_app_review package (2.0.12 at the time of writing) exposes requestReview() and openStoreListing():
import 'package:in_app_review/in_app_review.dart';
final inAppReview = InAppReview.instance;
Future<void> maybeAskForReview(bool eligible) async {
if (eligible && await inAppReview.isAvailable()) {
await inAppReview.requestReview();
}
}
// For a permanent "Rate us" menu item, which is not quota-limited:
Future<void> openRatingPage() => inAppReview.openStoreListing();
The package's docs repeat Google's advice: do not call requestReview() from a button; use openStoreListing() for that.
The "Rate us" fallback link
For a settings menu item, link to the listing's reviews section. Expo's docs show the URL format with showAllReviews=true:
https://play.google.com/store/apps/details?id=com.example.app&showAllReviews=true
market://details?id=com.example.app&showAllReviews=true
On iOS the equivalent is Apple's rating prompt plus the action=write-review link to the App Store. If you ship on both stores, our guide on responding to app reviews covers what to do once those reviews arrive.
![]()
The in-app review card only works when a genuine Google Play Store app is on the device, which is why emulators without Play and sideloaded stores fail. Photo: Nothing Ahead / Pexels
How to test the Google Play In-App Review API
Google's testing guide offers three methods, and picking the wrong one is the most common reason developers think the integration is broken.
| Method | What it is good for | Limits |
|---|---|---|
| Internal test track | End-to-end test with the real card | Quota is not enforced on this track |
| Internal app sharing | Fast iteration on a new build | Reviews "can't be submitted"; the button is disabled |
FakeReviewManager |
Unit and integration tests | No UI at all; always returns success |
For the internal test track, Google lists four conditions, and every one must be true:
- The user account is part of the internal test track.
- It is the primary account and is selected in the Play Store.
- It has downloaded the app from the Play Store, so the app is in that account's Google Play library.
- It does not already have a review for the app.
Once that account has installed the app once from the test track, you can deploy new builds to the device from Android Studio and keep testing. The app does not have to be published, but its application ID must exist at least on the internal testing track.
For automated tests, swap in the fake manager:
val manager: ReviewManager =
if (BuildConfig.DEBUG) FakeReviewManager(context) else ReviewManagerFactory.create(context)
In-App Review API not showing? A troubleshooting table
The causes below come from Google's troubleshooting list and from the long Stack Overflow thread on the subject, where developers describe a brief flicker and then nothing.
| Symptom | Likely cause | Fix |
|---|---|---|
| Flow completes, no card, in a debug build | App not installed from Play for this account | Install once from the internal test track, then deploy locally |
| Card worked once, never again | Quota reached, or you already reviewed | Delete your review in the Play Store, or use the internal test track |
| Card shows but Submit is greyed out | Installed through internal app sharing | Expected; use the internal test track to submit |
| Never shows on a work phone | Protected (enterprise) account | Test with a personal Gmail account |
PLAY_STORE_NOT_FOUND |
Emulator without Play, or sideloaded Play Store | Use a device or emulator image with Google Play |
| Never shows in production for some users | Quota, or they already reviewed | Expected; check your trigger logic is not burning calls early |
| Works on one test account, not another | Wrong primary account selected in Play Store | Switch the Play Store to the tester's account |
If none of those fit, log the ReviewErrorCode from requestReviewFlow() and confirm your trigger code runs at all. A surprising number of "not showing" reports are an eligibility check that never returns true.
A checklist before you ship
-
com.google.android.play:review(2.0.2 at the time of writing) added, or the Expo, React Native or Flutter wrapper. - An eligibility rule: several successful actions, a few days of use, a long gap between asks.
- The flow runs only at a success moment, never from a button or on first launch.
- No "Do you like the app?" question before the card, and no reward for rating.
-
onCompletealways continues the app; errors are logged, never shown. - A "Rate us" settings item opens the Play Store listing instead of the API.
- Tested end-to-end on the internal test track with a personal account that has not reviewed the app.
Ratings help people who already found your listing decide to install. Getting them to the listing is the other half: see our guides to Google Play ASO in 2026 and how to promote your app for free. If you are also reviewing what Google charges on the purchases those users make, read our breakdown of Google Play service fees in 2026. And for visibility outside the store, you can add your Google Play app to the AppRanker leaderboard, a pay-to-rank app listing where the order is a plain sort on what each listing has paid and every row links to your store page.
FAQ
How often can I show the Google Play in-app review dialog?
Google does not publish the number. It says calling the flow "more than once during a short period of time (for example, less than a month) might not always display a dialog", and that the quota can change without notice. Plan for one ask per user every few months at most.
Why is my in-app review dialog not showing?
In testing, usually because the app was not installed from the Play Store by the account you are using, the account already reviewed the app, or the quota was reached. Test on the internal test track with a personal account that has never reviewed the app. In production, the quota means some users will never see it.
Can I check whether the user left a review?
No. Google's sample code says: "The API does not indicate whether the user reviewed or not, or even whether the review dialog was shown." Continue your app's flow whatever happens.
Can I add a "Rate this app" button that opens the in-app review card?
Google advises against it, because a user who has hit the quota would tap the button and see nothing. Use the button to open your Play Store listing with showAllReviews=true instead.
Can I ask "Do you like our app?" first and only show the card to happy users?
No. Google says your app "shouldn't ask the user any questions before or while presenting the rating button or card", including questions about their opinion. Ask for the review at a success moment and let every user rate.
Does the in-app review API work in an emulator?
Only in an emulator image that includes the Google Play Store, signed in with an account that installed the app from Play. Without the Play Store you will get PLAY_STORE_NOT_FOUND.
Do reviews left during testing show publicly?
Not from a closed test track: Google's data safety notes say that if the app is in a closed test track, "the data collected is shared privately with the app developer." Reviews from internal app sharing cannot be submitted at all.
Image credits
- Cover, five wooden star blocks on an orange background: photo by Ann H on Pexels, Pexels License. Cropped to 1200x630.
- A hand holding an Android phone: photo by Zain Ali on Pexels, Pexels License. Resized.
- An Android home screen with the Play Store icon: photo by Nothing Ahead on Pexels, Pexels License. Resized.


