How to Intercept Negative Reviews Before They Hit the App Store

Stan
Stan

02 Mar 2025

A single one-star review can undo months of hard-earned five-star ratings. For apps with a small review base, a handful of negative ratings can noticeably drop your average — and once your rating slips, downloads tend to follow. The worst part: many of these negative reviews are preventable if you catch unhappy users before they post.

In this guide, we'll walk through a multi-step review interception pattern that routes unhappy users to an in-app feedback form while directing satisfied users to the native review dialog. The result: negative feedback stays private and actionable, while your public rating climbs. We'll implement the entire flow using the Amply SDK.


The Multi-Step Review Interception Pattern

  1. Show your own rating popup after a value moment

    Your app renders an in-app prompt asking the user to rate their experience from 1 to 5 stars. This popup lives entirely in your code — Amply does not draw UI. Amply's role here is timing: deciding when to tell your app to open it.

  2. Route based on the rating using two Amply campaigns

    Users who give 4-5 stars get the native Rate Review action, which invokes the platform's in-app review dialog. Users who give 1-3 stars get a Deeplink action that opens your in-app feedback form.

  3. Capture negative feedback privately

    The feedback form collects the reason for dissatisfaction, which you can track, categorize, and act on — without it ever becoming a public review.

The goal isn't to suppress negative feedback. It's to give yourself a chance to fix the problem before it becomes permanent public damage.

Step 1: The Custom Rating Popup

Timing is everything. The rating popup is a screen in your own app — typically a star selector on a dedicated route. You open it after a value moment: a completed workout, a saved draft, a successful checkout. One clean way to trigger it is an Amply campaign with a Deeplink action that points to that screen. When the user taps a rating, your app reports it back to Amply as an event and stores the last value as a custom property, so later campaigns can react to it:

// Android (Kotlin). 'amply' is the tools.amply.sdk.Amply instance you constructed
// in Application.onCreate (see the SDK setup guide).

// Track the rating event when the user submits
amply.track("CustomRatingGiven", mapOf(
    "rating" to selectedRating,
    "screen" to "post_workout_summary"
))

// Store as a custom property so later campaigns can target by rating
amply.setCustomProperties(mapOf(
    "last_custom_rating" to selectedRating
))

Step 2: Routing Happy vs. Unhappy Users

After the user submits their rating, your app fires the CustomRatingGiven event via amply.track(). Two separate Amply campaigns listen for that event as their Triggering Event, each filtered by a different Custom Property condition on last_custom_rating:

Campaign A: Happy Path (4-5 Stars)

Target users where the Custom Property last_custom_rating is >= 4. The campaign action is Rate Review, which invokes the platform's in-app review dialog — StoreKit on iOS, Google Play In-App Review on Android. On Android the real dialog only appears in Play Store-distributed release builds; debug builds show Google's fake review manager dialog, so don't judge the UX from a local run.

Campaign B: Recovery Path (1-3 Stars)

In the Who step, add a Custom Property rule: last_custom_rating (Number) is < 4. The campaign's action is a Deeplink pointing to a URL your app understands — for example happens://feedback-form. When the campaign fires, the SDK calls your registered deeplink listener with that URL, and your app routes to the feedback form. (The happens:// scheme is just a convention; use whatever scheme your app already registers.)

// Android (Kotlin). Handle the feedback-form deeplink in your app.
// Register once, e.g. in Application.onCreate after you create 'amply'.
import tools.amply.sdk.actions.DeepLinkListener

amply.registerDeepLinkListener(object : DeepLinkListener {
    override fun onDeepLink(url: String, info: Map<String, Any>): Boolean {
        if (url.contains("feedback-form")) {
            showFeedbackForm()
            return true
        }
        return false
    }
})

The branching lives in Amply, not in your app. Your app only fires one event — CustomRatingGiven — and sets one Custom Property. Two campaigns listen for that event with different Who-filters on last_custom_rating, so exactly one of them matches for any given user. To change the threshold from 4 to 5, or to add a third bucket, you edit the campaigns in the dashboard — no app release.


Step 3: The In-App Feedback Form

Keep it short — a category selector and a free-text field are usually enough. When the user submits, track the feedback with structured event parameters:

// Android (Kotlin). Track negative feedback with categorized reasons.
amply.track("NegativeFeedbackProvided", mapOf(
    "reason" to "app_crashes",
    "rating" to 2,
    "detail" to "Crashes every time I open settings"
))
Every piece of negative feedback that stays in-app is a one-star review that never reaches the App Store.

Setting Up with Amply

  1. Campaign 1 — open the rating screen after a value moment

    Triggering Event: your value-moment event (e.g. WorkoutCompleted). Action: Deeplink to the rating screen your app renders (e.g. happens://rating-prompt). Frequency Limits: 1 time per session, plus a lifetime cap if you don't want it to reappear forever. Remember: Amply only deeplinks; your app draws the actual rating UI.

  2. Campaign 2 — ask happy users for a store review

    Triggering Event: CustomRatingGiven. Who: Custom Property last_custom_rating (Number) >= 4. Action: Rate Review. On Android, this invokes the Google Play In-App Review dialog in release builds; debug builds get the fake review manager UI.

  3. Campaign 3 — route unhappy users to your feedback form

    Triggering Event: CustomRatingGiven. Who: Custom Property last_custom_rating (Number) < 4. Action: Deeplink to a URL your app routes to the feedback form (e.g. happens://feedback-form).


Code Implementation

// Android (Kotlin). 'amply' is the tools.amply.sdk.Amply instance from Application.onCreate.
import tools.amply.sdk.actions.DeepLinkListener

// 1. Register your deeplink listener once at app startup.
amply.registerDeepLinkListener(object : DeepLinkListener {
    override fun onDeepLink(url: String, info: Map<String, Any>): Boolean {
        return when {
            url.contains("rating-prompt") -> { showRatingPrompt(); true }
            url.contains("feedback-form") -> { showFeedbackForm(); true }
            else -> false
        }
    }
})

// 2. When the user submits a rating in your in-app popup.
fun onCustomRatingSubmitted(rating: Int, screen: String) {
    amply.track("CustomRatingGiven", mapOf(
        "rating" to rating,
        "screen" to screen
    ))
    amply.setCustomProperties(mapOf(
        "last_custom_rating" to rating
    ))
}

// 3. When the user submits the in-app feedback form.
fun onFeedbackSubmitted(reason: String, rating: Int, detail: String) {
    amply.track("NegativeFeedbackProvided", mapOf(
        "reason" to reason,
        "rating" to rating,
        "detail" to detail
    ))
}

Three functions on your side. The Amply dashboard owns the rest: targeting by Custom Property, Frequency Limits, and which action fires — Rate Review or a Deeplink to your own screen. If you want to move the threshold from 4 to 5, or add a brand-new bucket, you change it in the dashboard without a release.


Measuring the Impact

  • 1-2 star App Store review reduction

    Compare weekly low-star reviews before and after launch. The size of the drop will depend on how often your app hits a true value moment and how honest your rating UI is — Amply lets you measure it for your app, rather than rely on a generic benchmark.

  • Average rating trajectory

    Track your rolling 30-day average rating and watch whether it trends up after launch. A flat line is still a signal — it may mean your value-moment trigger needs tuning.

  • Feedback category distribution

    Aggregate the reason parameter from NegativeFeedbackProvided events to prioritize fixes.

  • Interception rate

    Percentage of low-rating users who submit feedback through the in-app form instead of going to the App Store.


Conclusion

Negative App Store reviews are not inevitable. With a well-designed interception pattern, you can catch dissatisfied users at the moment of frustration, give them a private channel to voice their concerns, and earn the chance to fix the problem before it becomes public.

The pattern we've built — rating popup rendered by your app, two Amply campaigns for routing, in-app feedback form — keeps client code small and moves the tunable parts (threshold, frequency caps, targeting) into the dashboard. As long as your app's rating and feedback screens are already wired to deeplinks, you can adjust the flow without a release. Stop treating negative reviews as an unavoidable cost. Start intercepting them.