How to implement Shorebird Code Push in Flutter?

Yii Chen
Flutter Taipei
Published in
13 min readApr 23, 2024

--

Wow! We can instantly update online products.

What is Code Push? It can be called Over The Air updates (OTA), allowing developers to push the latest version to online applications instantly.

As long as you are a mobile developer, whether you are developing natively or cross-platformly, you will encounter product review obstacles. Even small feature updates and bug corrections require resubmitting a version of the app to the store for official review. During this process, we will not know how long it will take, detailed inspection steps, or new passing conditions. We can only wait for 1 day or even several days to know the results. Everyone hopes that Mobile Apps can be updated and used as quickly as the Web, solve problems quickly, and provide users with the best experience.

The emergence of Shorebird is to solve this situation. The team launched Code Push last year, which allows developers to perform OTA updates for products and applications. This means that the new APP version code can be pushed directly to users’ mobile devices without going through the standard and complicated store review process. In addition, all operations are done through Shorebird CLI, which means we can easily integrate CICD tools such as Codemagic to simplify the process of deploying updates, which is very convenient.

For general end users, because of the Code Push update, after updating the APP in real-time, users can always access the latest version of the features without having to manually update through the Play Store and Apple Store.

Why name “Shorebird”?

Flutter’s first office was located on Shorebird Way in Mountain View.

https://twitter.com/_eseidel/status/1773178471189037535

Introduction

Authentication

Before anyone can use Shorebird, they must first authenticate. Common OAuth authentication ensures that only legitimate and authenticated users can access it.

Role Permissions

Typically, there are different positions within a development team such as Developer and Supervisor. We can define who has the authority to create patches and who can perform deployment-related operations

Instant updates

End users’ APPs can be updated in minutes, allowing any Dart Code changes to ensure that everyone can continue to access the latest features and optimizations

Easy Problem Solve

Resolve application issues quickly without unnecessary risk or stress

Strong Trust

Shorebard’s Code Push has been rigorously reviewed and approved by Apple and Google and also has product guarantees from founder Eric and many well-known developers. The team members are lean and highly active. Also ensure application updates are delivered with the highest level of security, using standard encryption and authentication methods to prevent unauthorized access.

Update Process

By default, Shorebird will background check and install new patches when the APP is launched. Processed through Background isolate to ensure that it does not affect the startup speed of the application. The patch installed this time can be used the next time you start the application.

Official

Shorebird Setup

Install Shorebird CLI, open Terminal, and enter commands

# macOS
curl --proto '=https' --tlsv1.2 <https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh> -sSf | bash

After the installation is complete, reopen the Terminal and enter the command. Click the login link to verify, that is a normal Google OAuth login.

shorebird login

At the moment, you will also receive the Shorebird welcome letter in your mailbox.

Shorebird Initialization

Open the Flutter project, add the configuration file, use it in the root directory of the project, and execute the following command:

shorebird init

Use the parameter --force to re-create the configuration file and directly overwrite the original data.

Shorebird will verify the flavor environment owned by the project and list all the things done, including the creation of shorebird.yaml file and adding shorebird.yaml for asset description.

The app_id in the shorebird.yaml file is used by Shorebird to identify the application, and the information inside does not need to be kept confidential.

Go to the Shorebird website to open the console and check the environment settings of the project.

Shorebird Release

Create a release version of the project and upload it to Shorebird Server. At the same time, the artifacts file for the corresponding platform will be generated. With Shorebird, you can use the shorebird release command to replace flutter build.

Four types of targets:

  • aar → Upload Android Library
  • android → Upload Android App (aab, apk)
  • ios → Upload iOS App
  • ios-framework → Upload iOS framework
shorebird release <target>

# Android
shorebird release android --artifact apk

Parameters available:

  • --target → The main program file of the project. The default is main.dart. Of course, you can also specify a flavor, for example, lib/main_dev.dart
  • --flavor → the flavor environment to be used
  • --artifact → File generated by Android. The default is aab, it can also be changed to apk

shorebird release like flutter build and can accept any original parameters. Remember to add two --separators before.

Android Release

shorebird release android -- --dart-define="key=xxxxxx"

A new artifact file will be generated locally. If it is aab, the log will remind you that you can upload this file to the Play Store. If it is an apk, you can install it directly to the simulator or physical device. At the same time, there will also be release records in the cloud.

If you execute the release command again, an error message will appear. Please bump your version number and try again. because the versions are the same. Each release represents a new change, so remember to modify the flutter version of pubspec.yaml, or delete the release record on the cloud, so that the release will be successful!

iOS Release

First, use shorebird release to build the iOS artifact of the project, usually an .ipa file.

shorebird release ios --flavor dev --target ./lib/main_dev.dart

Next is the process of deploying to the Apple Store. This is a manual demonstration, so we handle it from XCode and provide several steps:

Step 1. After the release is published to Shorebird Server, we can find the Runner.xcarchive file and double-click to open it.

Step 2. It is the normal Archives process, select “Distribute App”.

Step 3. Normally, you choose the TestFlight & App Store option, but because Shorebird requires different settings, you choose “Custom”.

Step 4. Click “App Store Connect” normally.

Step 5. This step is the most important. You need to cancel the “Manage version and build number” and do not need to update the version information.

Step 6. Then select the correct development certificate and Profile to upload to the Apple Store. Developers can also conduct subsequent testing (including patch updates) through TestFlight.

Remove Release

You can delete the release version originally published to the cloud, but remember that this operation is irreversible.

shorebird releases delete

#flavor
shorebird releases delete --flavor dev

Shorebird Preview

After a Shorebird release is released, you can use commands to preview the new release on emulators and devices. Download the release artifacts file, install the application on the device, and launch the application. Typically used in the development and CI/CD process.

shorebird preview

Shorebird Patch

Publish the patch for the current release version and update it for users using this version. When the developer releases a patch, the user’s application can be downloaded, and then the new Dart code can be run directly the next time it is opened.

Patch does not change the version number of the current application. It is applied to the existing version, not the new version.

Patch update process:

  1. Create updated artifact
  2. Download the corresponding release artifact
  3. Check the differences between the new version and the old version, and generate patch artifacts
  4. Upload the patch to Shorebird Server
  5. Upgrade patches to stable channel
shorebird patch android

shorebird patch ios

# args
shorebird patch android --flavor dev --target ./lib/main_dev.dart -- --dart-define="key=xxxxxx"

Flutter Development

First, add the Shorebird package shorebird_code_push to the project.

flutter pub add shorebird_code_push

The main APIs of the suite include:

  • Check if the device supports Shorebird
  • Get the currently installed patch version
  • Get the next patch version
  • Check if new patches are available for download
  • Download new patch

💡 Check if new patches are available for download

shorebirdCodePush.isNewPatchAvailableForDownload()

💡 Download new patch

shorebirdCodePush.downloadUpdateIfAvailable()

After we download the new patch in the initial stage of the application, it needs to be restarted for it to be effective and to execute the new version of Dart code. Therefore, it is recommended that the user be reminded that the update is completed and the application will be restarted at this time. Try to allow the user to manually click before taking action, so as not to restart suddenly and cause a bad experience.

You can refer to the official examples. There are several main steps we need to implement:

  1. Check if new patches are available for download
  2. There is a new patch, remind users to update
  3. The user actively performs updates
  4. Display updating status messages to let users know what they are currently doing
  5. Download new patches
  6. Display a status message that the update is completed, allowing the user to restart the APP and use the new features.
  7. Restarting can be performed with the help of the restart_app package.
final isUpdateAvailable =
await _shorebirdCodePush.isNewPatchAvailableForDownload();
if (!mounted) return;
setState(() {
_isCheckingForUpdate = false;
});
if (isUpdateAvailable) {
_showUpdateAvailableBanner();
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('No update available'),
),
);
}
}
void _showDownloadingBanner() {
ScaffoldMessenger.of(context).showMaterialBanner(
const MaterialBanner(
content: Text('Downloading...'),
actions: [
SizedBox(
height: 14,
width: 14,
child: CircularProgressIndicator(
strokeWidth: 2,
),
),
],
),
);
}
void _showUpdateAvailableBanner() {
ScaffoldMessenger.of(context).showMaterialBanner(
MaterialBanner(
content: const Text('Update available'),
actions: [
TextButton(
onPressed: () async {
ScaffoldMessenger.of(context).hideCurrentMaterialBanner();
await ㄎ();
if (!mounted) return;
ScaffoldMessenger.of(context).hideCurrentMaterialBanner();
},
child: const Text('Download'),
),
],
),
);
}
void _showRestartBanner() {
ScaffoldMessenger.of(context).showMaterialBanner(
const MaterialBanner(
content: Text('A new patch is ready!'),
actions: [
TextButton(
// Restart the app for the new patch to take effect.
onPressed: Restart.restartApp,
child: Text('Restart app'),
),
],
),
);
}
Future<void> _downloadUpdate() async {
_showDownloadingBanner();
await _shorebirdCodePush.downloadUpdateIfAvailable(),
if (!mounted) return;
ScaffoldMessenger.of(context).hideCurrentMaterialBanner();
_showRestartBanner();
}

Remember! To disable active updates by default, set auto_update in shorebird.yaml to false.

Why do you need manual updates or program code control? There are several benefits:

  1. Control the installation of patches (e.g. update only certain accounts at a time, users with specific permissions, AB Testing to reduce server load or reduce rollout risk).
  2. Respect users, give users security confirmation, and allow users to proactively update.

Android Setting

Shorebird Code Push requires network permissions so that the program can communicate with the Shorebird server and users can download patches to local updates. Need to modify the AndroidManifest.xml file,

<manifest>
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>

If the permissions do not exist when executing shorebird init, the permissions will be added automatically.

Example

Android

Demonstrates using Dart code to trigger updates. First, perform a Shorebird release on the previous version. This version will normally be the version released to the Play Store.

Use instructions for the specified environment and use Android for demonstration, so select the apk file here.

shorebird release android --flavor dev --target lib/main_dev.dart --artifact apk

Find the Android .apk file and install it on your Android phone to test.

Install the .apk file on your phone, which can be simulated as downloading from the store. The following is the initial screen of the APP. If you find a bug in the screen or function at this moment, you need to urgently release a patch through Shorebird to correct the problems encountered by users.

This example adjusts the text and background color of the button, changes some code, and publishes the new version using the shorebird patch command.

shorebird patch android --flavor dev --target lib/main_dev.dart

Check the release version in Shorebird Cloud, if there is a release, download it and combine it with the new code.

After the pre-work is completed, it will ask whether to create a patch and upload the generated artifacts to Shorebird Cloud. At this time, the end user will detect the new patch.

The Patches page will display all information about the deployment. Patch #2 is the patch just created.

iOS

Releasing the iOS version is a bit more complicated. First, use the shorebird release command to build the shorebird artifact, and then upload it to the Apple Store.

shorebird release ios --flavor prod --target lib/main_prod.dart

This example is the same as Android. It adjusts the text and background color of the button, changes the code, and releases the new version using the shorebird patch command (here you need to ensure that the Flutter version of the patch is the same as the Shorebird Release version)

shorebird patch ios --flavor prod --target ./lib/main_prod.dart

Demo

  1. First, install the release version of the APP through apk or TestFlight, then open it to display the first version.
  2. Change Dart code, and button configuration on the APP initial page, including text and background color
  3. Publish Shorebird Patch based on the same version
  4. When the user restarts the APP, the new patch is checked and downloaded, and the APP is restarted after completion.
  5. After opening, it will be the new version of the patched APP, using the new Dart code
Android
iOS

After users download the patch, the team can browse the current usage status from the Insights tab in the console.

Check and Update Timing

  1. When the default is active update, users can be reminded through push notifications. When clicking the notification to open the APP, it will also trigger the start of the Flutter engine, so Shorebird will download the patch and update the APP.
  2. In the case of manual updates and code updates, patches can be checked and downloaded periodically when the application is started or while it is running. When a new version of the patch is available, we can notify users through Dialog, Snackbar, Toast, etc., allowing them to click and restart the APP for updates.

Q/A

Q1: Which release version will be updated after the patch is released?

  • The current patches are for the latest release version, so users need to install the latest release first before they can perform Code Push updates through the patch.
  • For users of older versions, the forced update mechanism in the app can be used to guide users to download the latest version of the store first, which is the Shorebird release version. In this way, the application can be updated through patches later.

Q2: Shorebird manages our release version. Is there any risk if the official directly code pushes the customer’s product?

  • No, the official currently guarantees that our project code will not be seen or stored. “Push to Deploy” is impossible without source code access

Official FAQ

Community

Join Shorebard’s Discord community to learn about the latest news, team progress, and development ideas, and interact with everyone there.

Waiting to be solved

Currently, the replacement and update of asset resource files are not supported (currently v1.0 stable has been released and should be processed soon)

Reference

--

--

Yii Chen
Flutter Taipei

Flutter Lover || Organizer FlutterTaipei || Writer, Speaker || wanna make Flutter strong in Taiwan. https://linktr.ee/yiichenhi