Skip to content

Setting Up the Rating & Review SDK

What you'll learn

  • Generating the Rating & Review SDK
  • Configuring the five-gate prompt evaluation system at runtime
  • Recording sessions and key events to drive the rating prompt
  • Using the analytics-friendly decision API to track why prompts were skipped
  • Understanding platform availability constraints on iOS and Android

Prerequisites

Step 1: Generate the Rating & Review SDK

The Rating & Review SDK is a Free tier brick.

bash
archipelago generate rating_review_sdk

There are no generation variables — all configuration happens at runtime through RatingPromptConfig registered in your DI module.

Step 2: Understand the Generated Structure

The Rating & Review SDK uses the API/Impl split pattern:

features/
└── rating_review/
    ├── rating_review_api/     # RatingReviewSDK contract + RatingPromptConfig + decision types
    └── rating_review_impl/    # Gate evaluation, persistence, and platform review request
        └── lib/src/
            ├── rating_review_sdk_impl.dart
            ├── data/           # Local storage for session/event counts
            ├── di/             # RatingReviewImplPackageModule
            └── domain/         # Gate evaluation logic

Features that trigger the rating prompt depend only on rating_review_api.

Step 3: Configure the Prompt Gates

Override RatingPromptConfig in your app's DI module before RatingReviewImplPackageModule is registered:

dart
// apps/my_app/lib/di/app_di_module.dart
@module
abstract class AppDIModule {
  @lazySingleton
  RatingPromptConfig get ratingPromptConfig => const RatingPromptConfig(
    minSessions: 3,         // Minimum app launches before showing the prompt
    minKeyEvents: 2,        // Minimum positive moments before showing the prompt
    cooldownDays: 30,       // Days to wait before asking again after a dismissal
    askOncePerVersion: true, // Reset gates when the app version changes
    iosAppStoreId: 'YOUR_APP_STORE_ID', // Required for openStoreListing() on iOS
  );
}

The five gates are evaluated in order on each shouldRequestReview() call:

  1. Platform availabilityin_app_review is supported on this device/OS version
  2. Session threshold — recorded sessions ≥ minSessions
  3. Key event threshold — recorded key events ≥ minKeyEvents
  4. Cooldown — enough days have passed since the last prompt
  5. Per-version gate — not yet shown in this app version (when askOncePerVersion is true)

All five must pass for the prompt to show.

Step 4: Record Sessions and Key Events

Call recordSession() once per app launch, early in your post-launch phase:

dart
// apps/my_app/lib/post_launch_initializer.dart
await getIt<RatingReviewSDK>().recordSession();

Call recordKeyEvent() after a meaningful positive interaction — checkout completion, a successful upload, or any moment of clear user satisfaction:

dart
// In your order confirmation screen or usecase
await getIt<RatingReviewSDK>().recordKeyEvent('checkout_completed');
await getIt<RatingReviewSDK>().recordKeyEvent('photo_shared');

Key event names are arbitrary strings; use them to distinguish event types in your analytics if needed.

Step 5: Show the Rating Prompt

Check the gates and show the prompt after a positive moment:

dart
final ratingSDK = getIt<RatingReviewSDK>();

await ratingSDK.recordKeyEvent('subscription_activated');

if (await ratingSDK.shouldRequestReview()) {
  await ratingSDK.requestReview();
}

requestReview() delegates to the platform's native in-app review UI. On iOS this is SKStoreReviewController; on Android it is the Google Play In-App Review API. The OS controls whether the dialog actually appears — calling requestReview() is a hint, not a guarantee.

Step 6: Use the Decision API for Analytics

evaluatePromptDecision() returns a typed decision instead of a boolean, which lets you track skip reasons without duplicating the gate logic:

dart
final ratingSDK = getIt<RatingReviewSDK>();
final decision = await ratingSDK.evaluatePromptDecision();

switch (decision) {
  case RatingPromptDecisionShow():
    await ratingSDK.requestReview();
    analytics.track('rating_prompt_shown');

  case RatingPromptDecisionSkip(:final reason):
    analytics.track('rating_prompt_skipped', {'reason': reason.name});
    // reason.name might be: 'platformUnavailable', 'sessionThreshold',
    // 'keyEventThreshold', 'cooldown', or 'perVersionGate'
}

This makes it straightforward to measure prompt suppression rates per gate in your analytics dashboard.

After a positive review or to let users rate manually from a settings screen:

dart
// Opens App Store (iOS) or Play Store (Android) listing
await getIt<RatingReviewSDK>().openStoreListing();

On iOS, iosAppStoreId must be set in RatingPromptConfig for this to work. On Android, the Play Store app page is derived from the app's package name automatically.

Platform Notes

PlatformAvailability
iOSAvailable when iosAppStoreId is set and the app is on the App Store
AndroidRequires the app to be published (internal testing track is sufficient)
Debug buildsisAvailable() returns false on Android — the Play Store API requires a production or testing track build
iOS simulatorReview requests are silently ignored by the OS

If isAvailable() returns false, shouldRequestReview() will also return false via the platform availability gate, so no special handling is needed in your feature code.

Common Customizations

GoalWhat to do
Lower threshold for testingSet minSessions: 1, minKeyEvents: 1 in a debug DI override
Disable per-version gatingSet askOncePerVersion: false
Show prompt after a specific screen onlyCall shouldRequestReview() in that screen's initState or onResume
Reset all countersCall ratingSDK.reset() (useful for QA testing)
Surface the prompt after onboardingRecord a 'onboarding_completed' key event at the end of onboarding

Next Steps

Built by Banua Coder