Flutter Package

firebase_update

Control Flutter releases with updates, maintenance mode, and live configuration.

Q

Qoder

9 sectionsFlutter Package

Overview

firebase_update gives Flutter apps server-controlled release behavior through Firebase Remote Config. Product and engineering teams can block unsupported builds, suggest optional upgrades, turn on maintenance mode, and show patch notes without waiting for a new app release.

Features

Everything needed for production update control, with defaults that work and hooks for teams that need branded surfaces.

  • Force Update — blocks app usage when a breaking release is required
  • Optional Update — encourages upgrade via a dismissible dialog or bottom sheet
  • Maintenance Mode — instantly gates the app without shipping a new build
  • Real-time Remote Config propagation — changes apply without app restart
  • Patch notes displayed in plain text or HTML alongside the update prompt
  • FirebaseUpdateBuilder — reactive widget for custom in-screen update surfaces
  • Fully custom UI builders — override one, two, or all three surfaces independently
  • Store-version fallback checks when listing data is useful

Installation

Requires Firebase to already be set up in your app.

Dart
dependencies:
  firebase_update: ^1.0.0

Quick Start

Call initialize() once during app bootstrap, after Firebase.initializeApp(). Pass the same navigatorKey to your MaterialApp. The package then listens for Remote Config changes and automatically presents the appropriate UI.

Dart
import 'package:firebase_update/firebase_update.dart';

final navigatorKey = GlobalKey<NavigatorState>();

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  await FirebaseUpdate.instance.initialize(
    navigatorKey: navigatorKey,
    config: const FirebaseUpdateConfig(),
  );

  runApp(MyApp(navigatorKey: navigatorKey));
}

// Pass the same navigatorKey to MaterialApp
MaterialApp(
  navigatorKey: navigatorKey,
  home: const HomeScreen(),
)

Remote Config Schema

Create a parameter named firebase_update_config in Firebase Remote Config, or pass a custom key. Priority order is intentionally strict: maintenance mode wins over force update, and force update wins over optional update.

Dart
{
  "min_version": "2.0.0",
  "latest_version": "2.3.1",
  "maintenance_message": "",
  "patch_notes": "• Bug fixes\n• Performance improvements",
  "patch_notes_format": "text"
}
  • min_version — minimum supported version; below this triggers a blocking force update
  • latest_version — latest available version; below this triggers an optional update
  • maintenance_message — non-empty string activates maintenance mode (blocking)
  • force_update_title & force_update_message — override the force update screen copy
  • patch_notes — release notes shown alongside the prompt (format: text or html)

Custom UI & Theming

Override any surface directly on FirebaseUpdateConfig. Each builder receives resolved presentation data, state, action labels, and callbacks, so teams can keep update flows consistent with their brand and navigation model.

Dart
// Override individual surfaces
FirebaseUpdateConfig(
  forceUpdateWidget: (context, data) => MyForceUpdateDialog(data: data),
  optionalUpdateWidget: (context, data) => MyUpdateSheet(data: data),
  maintenanceWidget: (context, data) => MyMaintenanceScreen(data: data),
)

// Theme the default UI
FirebaseUpdatePresentation(
  theme: FirebaseUpdatePresentationTheme(
    accentColor: Colors.indigo,
    accentForegroundColor: Colors.white,
    surfaceColor: Colors.white,
    heroGradient: LinearGradient(
      colors: [Colors.indigo.shade800, Colors.indigo.shade400],
    ),
    dialogBorderRadius: BorderRadius.circular(24),
  ),
)

Reactive Widget

Use FirebaseUpdateBuilder to build your own in-screen update surfaces — a settings row, a banner, or anything that should react to update state.

Dart
FirebaseUpdateBuilder(
  builder: (context, state) {
    if (state.kind == FirebaseUpdateKind.optionalUpdate) {
      return UpdateBanner(version: state.latestVersion);
    }
    return const SizedBox.shrink();
  },
)

API Reference

Core API for controlling update behavior programmatically.

Dart
// Initialize once at app startup
await FirebaseUpdate.instance.initialize(
  navigatorKey: navigatorKey,
  config: config,
);

// Force an immediate fetch and re-evaluate state
await FirebaseUpdate.instance.checkNow();

// Current state (synchronous) or stream (reactive)
FirebaseUpdateState state = FirebaseUpdate.instance.currentState;
Stream<FirebaseUpdateState> stream = FirebaseUpdate.instance.stream;

// Apply a raw payload manually (useful in tests)
await FirebaseUpdate.instance.applyPayload({'min_version': '2.0.0'});

Testing

A Dart CLI tool in test/firebase_config/ pushes predefined scenarios directly to Firebase Remote Config, leaving all other parameters untouched. The running app reacts in real time.

Dart
cd test/firebase_config
dart pub get

# Push test scenarios:
dart run update_remote_config.dart optional
dart run update_remote_config.dart force
dart run update_remote_config.dart maintenance
dart run update_remote_config.dart clear