🦦

Shorebird【Flutter】リリースしたアプリがクラッシュしたのでCodePush実装

2024/09/13に公開

アプリの配布情報

  • AppStore、Google Playで配布
  • フレームワーク:Flutter
  • 開発言語:Dart

事象と対応

ここ数日の出来事でアプリが起動しないことが発覚、起動時にスプラッシュ画面から進まない。
※お恥ずかしい話、強制アップデートのプログラムは実装していたがその前でエラーが発生、firebaseコンソールからのプッシュ通知も届かず、、うつ手なしの状況でした。

原因(あえてここでは書きません)が判明し早急に対処し、各ストアに審査提出。

androidは1時間ぐらいで審査完了。

https://qiita.com/KaitoMuraoka/items/05ac3a9f7ffd7f0fed8d

AppStoreは上記を申請しました。

通常、日中に申請を出すと深夜(どっちかの夜は昼間〜♩)に審査が通ることが多いため、あまり期待していなかったのですが、今回は14時頃に申請して17時頃には完了し、非常に驚きました。

Shorebird実装へ

てなわけで、去年ぐらいから知っていたが必要になるかな?と思っていたShorebirdについて向き合ってみました。
https://shorebird.dev/
なるほど、料金面などは月のパッチインストール数で変化するのか。
とりあえず無料プランに加入する。
https://docs.shorebird.dev/
ドキュメントを読むんでやってみる。

環境、初期設定

1.curlでinstall

  1. プロジェクトRootでshorebirdにログイン
shorebird login

webでgoogle認証したあとなんかエラー出た

Waiting for your authorization...
The current version is not supported. Please upgrade to the latest version and try again.
The current version requires "code_push_client" >=0.8.0+1 <0.9.0.
Because the current version of "code_push_client" is 0.6.0+1, version solving failed.

もう一回、ドキュメント読み直しchatgptに聞きつつ下記をやってみる。

shorebird doctor

↓※これは必要ないかも

shorebird upgrade

もう一回ログイン

〇〇〇〇 % shorebird login

Choose an auth provider
❯ ◉  Google
Choose an auth provider Google
The Shorebird CLI needs your authorization to manage apps, releases, and patches on your behalf.

In a browser, visit this URL to log in:

https://accounts.google.com/o/oauth2/v2/auth?client_id=〇〇〇〇

Waiting for your authorization...

🎉 Welcome to Shorebird! You are now logged in as <〇〇〇〇@gmail.com>.

🔑 Credentials are stored in /Users/〇〇〇〇/Library/Application Support/shorebird/credentials.json.
🚪 To logout use: "shorebird logout".

ログイン完了。

3.続いて初期化かな

https://docs.shorebird.dev/code-push/initialize/

shorebird init

※上記を実行すれば、下記は自動でインストール。
https://pub.dev/packages/shorebird_code_push/install

実行完了後、shorebird.yamlが生成。

app_id: 〇〇〇〇
flavors:
  development:〇〇〇〇
  production: 〇〇〇〇

flavor対応自動でやってくれるのはありがたい。
ここまでで設定が完了。

release,prview,patch

▪︎release

shorebird release

うーむ、flutter versionとbuil_nameとbuild-numberとflavorどうやればいいんだと悩む。
chatgptにも聞いてみる。
fvmのコマンドと組み合わせできないやんと気づく。※出来た方いたらご教示ください。
※このアプリではdart defineは利用してません。

30分ぐらい悩んで

▪︎android

shorebird release android --flavor production --flutter-version 3.24.0 --target lib/main_production.dart --build-name 1.0.0 --build-number 1

▪︎ios版

shorebird release ios --flavor production --flutter-version 3.24.0 --target lib/main_production.dart --build-name 1.0.0 --build-number 1

上記で実行できた。
※細かくは書きませんが、筆者の場合は --flutter-versionのところは

FLUTTER_VERSION=$(grep '"flutterSdkVersion"' .fvm/fvm_config.json | sed 's/.*: "\(.*\)".*/\1/')

シェルスクリプト組んでfvmのflutterVersion取得実行してます。
なんかもっといい方法ありそう。


ShorebirdConsoleにアップ確認。

▪︎prview

実機でのテストを実行。
実機(android,ios)準備。

〇〇〇〇 % shorebird preview
Which app flavor?
❯ ◉  development
  ◯  production

flavor選択。

Which release would you like to preview?
❯ ◉  1.0.0+1(これはandroid)
  ◯  1.0.0+1(これはios)

android選択。

Which release would you like to preview? 1.0.0+1
✓ Fetching aab artifact (0.3s)
✓ Downloading release (0.3s)
✓ Using production track (0.7s)
✓ Extracting metadata (0.5s)
✓ Building apks (2.4s)
✓ Installing apks (9.1s)
✓ Starting app (0.4s)

Shorebird ConsoleからアップロードしたビルドがAndroid端末にデプロイ。

▪︎patch

少し、プログラムに変更を加えてみる。

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Hello World App'),
        ),
        body: const Center(
          child: Text('Hello World!'),
        ),
      ),
    );
  }
}

変更↓

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('shorebird patch'),
        ),
        body: const Center(
          child: Text('shorebird patch'),
        ),
      ),
    );
  }
}

その後、実行。(flavoerも含める)

▪︎android

shorebird patch android --flavor production --target lib/main_production.dart

▪︎ios

shorebird patch --platforms=ios --flavor=production --target=lib/main_production.dart

無事に、両方の端末でパッチの適用を確認できました!

筆者の解釈でのプロセス図(android、iosも同様と認識)

Roll backに関して

https://docs.shorebird.dev/code-push/rollback/

patch適用を元に戻す。

TestFlight版と内部テスト版を端末にインストールし、shorebird patchの適用確認も行いました。めでたし、めでたし。

ん?待てよ、今回はテストリリース版で実装できているかの確認のみなのに、このままではリリース済みのアプリにもshorebird patchが適用されるのではないか。

※再インストール後、2〜3回の起動でパッチの適用を確認。あー、パッチのインストール数(残り)にも影響が。

正しい使い方ではないかもしれませんが、Shorebird ConsoleからRollbackを実行しました。これは「パッチを元に戻した」というより「パッチの適用を停止した」という意味合いになります。
※Rollbackでは、Android Studio側(ローカル)のソースコードは元に戻りませんので注意。

最後に

一通り試してみた結果、致命的なクラッシュが発生した際にはshorebird patchを利用し、通常の改修リリースはこれまで通りの方法で問題ないという結論に至りました。これは、パッチインストール数に制限があるためです。

ただ、Webのように即時に反映できる手段があることは、最終的な対応策として心に余裕を持たせてくれますのでありがたいです。

皆様のお力になれれば幸いです。

Discussion