update_manager 1.2.0
update_manager: ^1.2.0 copied to clipboard
A Flutter package to manage app updates with Firebase Remote Config and Shorebird, supporting force, optional, and patch updates easily.
update_manager #
A Flutter package for managing app updates with Firebase Remote Config and Shorebird patch updates.
It helps you implement force updates, optional updates, and patch updates easily.
β¨ Features #
- π Force update when a critical version is required
- π’ Optional update when a newer version is available
- β‘ Patch updates via Shorebird
- π§ Configurable via Firebase Remote Config
- π― Simple integration with callback support
- π οΈ Example app included
π¦ Installation #
1. Add Dependencies #
Add this to your pubspec.yaml
:
dependencies:
update_manager: ^1.2.0
# Required dependencies
firebase_core: ^4.1.1
package_info_plus: ^9.0.0
2. Install Packages #
Run:
flutter pub get
3. Configure Firebase #
This package requires Firebase to be configured in your project. Follow the official Firebase setup guide for your platform:
Make sure to initialize Firebase in your main.dart
:
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(MyApp());
}
4. Setup Shorebird for Code Push Updates #
Install Shorebird CLI
Install Shorebird #
# Verify installation
shorebird --version
For more information, visit the Shorebird documentation.
π Usage #
Main Entry Points in Example/
#
main.dart
β Standard setup. Requires manual configuration of update checks and UI.main_default_ui.dart
β Comes with built-in update dialogs and patch UI. Minimal configuration required.
Tip: For quick setup with default UI, use main_default_ui.dart
.
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:update_manager/update_manager.dart';
const UpdateTrack kAppUpdateTrack = UpdateTrack.stable;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Update Manager Example',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Update Manager Example'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
UpdateManager? _updateManager;
final UpdateTrack _currentTrack = kAppUpdateTrack;
String _currentVersion = '';
int? _currentPatchNumber;
@override
void initState() {
super.initState();
_initialize();
}
Future<void> _initialize() async {
final packageInfo = await PackageInfo.fromPlatform();
setState(() {
_currentVersion = packageInfo.version;
});
if (!mounted) return;
// Configure UI preferences
final uiConfig = UpdateUIConfig(
dialogStyle: UpdateUIStyle.material,
patchUIStyle: PatchUIStyle.snackbar,
androidPlayStoreUrl: 'redirection link',
iosAppStoreUrl: 'redirection link',
showDefaultUI: true, // Set to false if using custom callbacks only
primaryColor: Colors.deepPurple,
accentColor: Colors.amber,
);
_updateManager = UpdateManager(
enableShorebird: true,
packageInfo: packageInfo,
uiConfig: uiConfig,
context: context,
);
try {
await _updateManager?.initialise(shorebirdTrack: _currentTrack);
final installedPatch = await _updateManager?.shorebirdService
?.readCurrentPatch();
if (mounted) {
setState(() {
_currentPatchNumber = installedPatch;
});
}
} catch (e) {
debugPrint("UpdateManager init error: $e");
}
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
backgroundColor: theme.colorScheme.inversePrimary,
title: Text(widget.title),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// Version Info Card
Card(
color: theme.colorScheme.primaryContainer,
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Text(
'Current Version',
style: theme.textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
_currentVersion,
style: theme.textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
color: theme.colorScheme.primary,
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.info_outline, size: 20),
const SizedBox(width: 8),
Text(
'Installed Patch: ${_currentPatchNumber ?? 'None'}',
style: theme.textTheme.bodyLarge?.copyWith(
fontWeight: FontWeight.w500,
),
),
],
),
],
),
),
),
const SizedBox(height: 24),
],
),
),
);
}
}
βοΈ Firebase Setup #
- Enable Remote Config in your Firebase Console.
- Add the following default parameters and values.
- Refer to
example/remoteconfig.template.json
for a complete example.
Key | Example Value | Description |
---|---|---|
min_required_version |
{"stable": "1.0.0", "beta": "1.0.5", "staging": "1.0.10"} |
Minimum app version required per track. JSON map of track versions ({"stable": "1.0.0", "beta": "1.0.5"} ). |
latest_version |
{"stable": "1.0.29", "beta": "1.0.30", "staging": "1.0.31"} |
Latest available version per track. JSON map of track versions ({"stable": "1.0.29", "beta": "1.0.30"} ). |
patch_enabled |
true |
Global flag to enable or disable patch checking. |
patch_info |
{ "1.0.25": { "stable": 1, "beta": 0, "staging": 0 }, "1.0.1": { "stable": 1, "beta": 2, "staging": 3 } } |
Patch numbers per version and track. The format is { "version": { "track": patchNumber } } . |
Example patch_info
value:
{
"1.0.25": { "stable": 1, "beta": 0, "staging": 0 },
"1.0.1": { "stable": 1, "beta": 2, "staging": 3 }
}
π Changelog #
See the Changelog
π± Example #
See the example/
folder for a full demo project.
π License #
This project is licensed under the MIT License.