Every production build automatically registered into a centralized database via the CI/CD pipeline.
Age-based thresholds pushed to Firebase Remote Config. Users get the right prompt at the right time.
One integration — mekari_flag handles everything. Flutter native, Android, and iOS via BrickWrap.
Each mobile app implements force update independently with inconsistent logic and thresholds. No standardized approach across Android and iOS — varied user experiences and redundant engineering effort per app.
Users on outdated versions (6+ months old) pose security, performance, and API compatibility risks. We can't accurately track version adoption rates or enforce updates without shipping a new release per app.
No mechanism to trigger update prompts based on version age. Teams manually monitor and update Firebase values — slow, error-prone, and with no standardized remote configuration system across all apps.
Security patches and critical fixes take too long to reach 100% of the user base. No centralized kill switch — resolving a critical bug requires a new build and release cycle for every affected app.
The result: Outdated versions generate more crashes, compatibility issues, and security exposure — while inconsistent update experiences damage brand trust and limit feature rollout velocity.
A centralized database that automatically captures every production mobile app release via the CI/CD pipeline.
Connects the Version Catalog to mobile clients via Firebase Remote Config. Engineers control when threshold changes reach users.
Production pipeline runs — app deployed to Play Store internal testing (Android) and TestFlight (iOS)
Pipeline calls Version Catalog API — registers build number, version name, timestamp
Older versions automatically marked deprecated
Release engineer manually promotes to "Go Live", or the daily scheduler detects the version is in production and auto-promotes
Ohara calculates age-based thresholds and pushes to Firebase Remote Config
App launches or resumes — SDK reads Firebase Remote Config
SDK compares installed version code against thresholds
Appropriate update UI shown — or nothing if version is current
inAppUpdateEnabled = true and the app is installed from the Play Store.force_update_config_adr
force_update_config_ios
{ "enabled": true, "soft_min_version_code": 2010, "strong_min_version_code": 2000, "force_min_version_code": 1090, "soft_update_cooldown_days": 30, "critical_min_version_code": 0 }
| Field | Type | Required | Description |
|---|---|---|---|
enabled |
Boolean | Yes | Kill switch. false disables all prompts without a client release |
soft_min_version_code |
Integer | Yes | Users below this version see the soft nudge (dismissible) |
strong_min_version_code |
Integer | Yes | Users below this version see the strong reminder (dismissible, no cooldown) |
force_min_version_code |
Integer | Yes | Users below this version see the force blocker (not dismissible) |
soft_update_cooldown_days |
Integer | No | Days between soft update appearances. Default: 30 |
critical_min_version_code |
Integer | No | 0 = disabled. Any positive value activates the critical tier (highest priority, manual only) |
Release engineer promotes a version to "Live" — Ohara recalculates thresholds and pushes to Remote Config automatically.
Pluton runs a daily check: if a deployed version is detected as live in the App Store or Play Store, it is automatically promoted — no engineer action needed.
Color-coded age badges (Current / Soft / Strong / Force) across all apps and platforms in one view.
Every Remote Config change logged — who promoted to Live, when, and for which app.
Fetches and caches Firebase Remote Config with a 10-second timeout. Falls back to last cached config on error — no prompts shown if no config available.
Compares installed version code against threshold values. Evaluates critical → force → strong → soft in priority order.
Single MpForceUpdate component for all tiers — dismissible page (soft/strong) or full-screen blocker (force/critical) with custom localized message.
Native in-app update API via Google Play for soft/strong (flexible) and force/critical (immediate). iOS uses store URL for all tiers.
Firebase Analytics events with force_update_ prefix — tier shown, tapped, dismissed, downloaded.
MpForceUpdate page with "Update now" and "Later".
Kotlin · calls ForceUpdateModule
ForceUpdateModule.kt
Native API layer
Flutter method channel bridge
ForceUpdateManager (Flutter)
Threshold values
Swift · calls ForceUpdateModule
ForceUpdateModule.swift
Native API layer
Flutter method channel bridge
ForceUpdateManager (Flutter)
Threshold values
Direct integration — no bridge needed
Threshold values
check() — shows update UI |
getTier() — silent tier query with no UI
check() on app launch & resume — that's the entire integrationmekari_flag version >= 1.8.0
await ForceUpdateManager .instance.check( context, product: MpForceUpdateProduct.talenta, inAppUpdateEnabled: true, onClose: (response) { // handle dismissal }, );
BrickWrap - brick_way v1.24.0
forceUpdateModule.check( context = this, product = ForceUpdateProduct.TALENTA, inAppUpdateEnabled = true, analyticsEnabled = true, // needed for Play Store flow launcher = activityResultLauncher ) // optional: silent tier check forceUpdateModule.getTier { tier -> // "none" | "soft" | "strong" // "force" | "critical" | null }
BrickWrap - brick_way v1.24.0
forceUpdateModule.check( presentingViewController: self, product: .talenta, inAppUpdateEnabled: true, analyticsEnabled: true ) { tier, shouldDismissApp in if shouldDismissApp { // handle dismissal } } // optional: silent tier check forceUpdateModule.getTier { tier in // "none" | "soft" | "strong" // "force" | "critical" | nil }
| Before | After Pluton | |
|---|---|---|
| Version tracking | Per-app, manual or none | Centralized, fully automatic |
| Update recommendation behaviour | Each app rolls its own | Unified process & SDK — Consistent UX & behavior across apps |
| Config per release | Manual calculation & update required | Automated calculation & updates |
| Version visibility | None | Full history with age and tier in Ohara |
| Audit trail | None | Every config change logged automatically |
| Ongoing dev effort | Per-release manual work | Zero — after initial integration |
One system. All platforms. Zero per-release effort.
Let's ship it.