Customize the "Upgrader" for your own app updates in Flutter
Background
Upgrader is a popular package for alert message to user for app updates if a new version is published in AppStore/PlayStore for Flutter. It’s so great to have a built-in Alert widget and Card widget, and also easy to use them following the guidance.
Why Customize it
- The bottom sheet alert looks better with the overall style of my app. Not aggressive as a dialog alert to occupy the “whole” screen.
- My app has three bundleIds in appstore connect for IAP testing(dev, beta and production). To test the Upgrader, changing the bundle id to production may break IAP and Firebase on production (seeing errors from Firebase in debug with production bundle id).
- The state of the UpgraderAlert will be rebuilt if the widget tree is rebuilt when wrap UpgraderAlert on the GoRouter builder.
Useful components in Upgrader
the package Upgrader is well-structured (thanks the author). List the components we will use:
- UpgradeAlert class: the alert widget, it’s used to wrap the child widget and will show the “alert” on top of the child widget.
- UpgradeAlertState class: the state of the alert widget, owns the detailed widgets.
- Upgrader class: the core logic of check the version if trigger the alert or not.
- UpgraderStore class: the abstract class for store version provider. It provides the latest app version information available in store.
How
Bottom Sheet Alert
UpgradeAlertState
can be extended and overridden with a customized alert widget, like dialog or bottom sheet.
- To popup a dialog: overwrite the
alertDialog
method, Upgrader author offers an example main_alert_theme. - To popup a bottom sheet: have to overwrite the
showTheDialog
method, this is the caller of abovealertDialog
. There is a similar example too main_custom_alert but not a bottomsheet.
Mockup version provider for test
To test the updates without changing bundleId and app description stored, we can rewrite the UpgraderStore
to provide a dummy versions for testing.
Avoid rebuilding
The UpgradeAlert is placed just under the MaterialApp
widget (following the guidance), almost at the root of the widget tree. If the Upgrader is running in Debug mode, you may notice the Upgrader’s debug output when widget tree is rebuilt.
The whole widget tree may be rebuilt multiple times (by designed in Flutter).
To minimize the rebuilding cost in UpgradeAlert, we can wrap UpgradeAlert
(or UpgradeCard
) within a page and use the upgrader.shouldDisplayUpgrade
to control the trigger.
Code
The mock up class will provide the url, appStoreVersion, release note and minimal app version for testing. This will help your quick test without changing bundle id.
Initialize the Upgrader
before the MaterialApp
, inject the mockup data into the Controller
.
upgrader.initialize()
query the store’s server (AppStore and PlayStore) on production, this only calls once in the app’s lifecycle.
On non-production, no call to store’s server, just use the mockup data.
Customize the UpgradeAlert
with a BottomSheet.
We have initialized the upgrader
before, so use it to gate the trigger.
It’s possible to have multiple calls to shouldDisplayUpgrade
if widget tree is rebuilt.
No worries, this method only use the on-hand data (cached) to check, no calls to store’s server or no widget updates.
Other tricks
During my testing, noticed the hot reload
may not pick the mocked up version changes sometimes, have to restart the app.
And also, if the ‘Update Now’ button doesn’t work (click but nothing happened), check if the alert (dialog or bottomsheet) is double triggered, the second trigger may have an empty url.
Updates
Created on 2024-06-04