🌊
【Flutter】Firestoreを用いて強制アップデートを実装する
はじめに
「Flutter 強制アップデート」で調べるとFirebaseのRemoteConfig で実装する例をよく目にします。
RemoteConfigでの実装例はこちらの記事がとてもわかりやすかったです。
しかしこちらの実装を終えてみて、わざわざRemoteConfigを設定せずにFirestoreでよくね?と思ったのでFirestoreでの実装例を紹介させていただきます!
またこちらの個人開発アプリで実際に実装してみたので、アプリについて宣伝させていただきます!
二郎好きの方はぜひ使ってみてください!
完成例
全体像
強制アップデートはRemoteConfigでもFirestoreでもやることは同じで
1. 現在のアプリのバージョンを確認する
2. アップデートしたいバージョンをFirestore(or RemoteConfig)から取得する
3. 現在のアプリバージョンがアップデートしたいバージョンより低ければ強制アップデートのダイアログを表示させる
というシンプルなものになります。
この順番に実装例をご紹介します!
実装例
前提
Firebaseの設定を行なっていること
必要なパッケージ
pubspec.yaml
dependencies:
cloud_firestore: ^2.3.0
firebase_core: ^1.10.0
package_info: ^2.0.2 //アプリのバージョンを取得
url_launcher: ^6.0.17 //ストアを開く
version: ^2.0.0 //なくても良い(1.0.3と1.0.4を簡単に比較できるようになる)
pubspec.yamlに記述し pub get
Firestoreにアップデートしたいバージョンを入れる
以下のようにconfigコレクションにios_force_app_versionを作成する。(Androidも実装する場合は別で値を作成する。今回は省略)
現在のアプリバージョンを確認する
package_infoを用いて現在のアプリのバージョンを取得します。
final info = await PackageInfo.fromPlatform();
final currentVersion = Version.parse(info.version);
Firestoreからアップデートしたいバージョンを取得する。
さきほどFirestoreに入れたバージョンをアプリ側で取得する
final doc = await FirebaseFirestore.instance
.collection('config')
.doc('- ドキュメントIDを指定する -')
.get();
final newVersion = Version.parse(doc.data()!['ios_force_app_version'] as String);
現在のバージョンとFirestoreから取得したバージョンを比較してダイアログを出す
//現在のバージョンがアップデートしたいバージョンより低ければダイアログを出す。
if (currentVersion < newVersion) {
showUpdateDialog(context);
}
ダイアログ
// FIXME ストアにアプリを登録したらurlが入れられる
static const appStoreURL =
'https://apps.apple.com/jp/app/id[アプリのApple ID]?mt=8';
/// ダイアログを表示
void showUpdateDialog(BuildContext context) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
const title = 'バージョン更新のお知らせ';
const message = '新しいバージョンのアプリが利用可能です。ストアより更新版を入手して、ご利用下さい。';
const btnLabel = '今すぐ更新';
return CupertinoAlertDialog(
title: const Text(title),
content: const Text(message),
actions: <Widget>[
TextButton(
child: const Text(
btnLabel,
style: TextStyle(color: Colors.red),
),
onPressed: () async {
if (await canLaunch(appStoreURL)) {
await launch(
appStoreURL,
forceSafariVC: true,
forceWebView: true,
);
} else {
throw Error();
}
},
),
],
);
},
);
}
全体のコード
//アプリ起動時に呼ぶ
Future<void> versionCheck() async {
//アプリのバージョンを取得
final info = await PackageInfo.fromPlatform();
final currentVersion = Version.parse(info.version);
//Firestoreからアップデートしたいバージョンを取得
final doc = await FirebaseFirestore.instance
.collection('config')
.doc('- ドキュメントIDを指定する -')
.get();
final newVersion = Version.parse(doc.data()!['ios_force_app_version'] as String);
//バージョンを比較し、現在のバージョンの方が低ければダイアログを出す
if (currentVersion < newVersion) {
showUpdateDialog(context);
}
}
// FIXME ストアにアプリを登録したらurlが入れられる
static const appStoreURL =
'https://apps.apple.com/jp/app/id[アプリのApple ID]?mt=8';
/// ダイアログを表示
void showUpdateDialog(BuildContext context) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
const title = 'バージョン更新のお知らせ';
const message = '新しいバージョンのアプリが利用可能です。ストアより更新版を入手して、ご利用下さい。';
const btnLabel = '今すぐ更新';
return CupertinoAlertDialog(
title: const Text(title),
content: const Text(message),
actions: <Widget>[
TextButton(
child: const Text(
btnLabel,
style: TextStyle(color: Colors.red),
),
onPressed: () async {
if (await canLaunch(appStoreURL)) {
await launch(
appStoreURL,
forceSafariVC: true,
forceWebView: true,
);
} else {
throw Error();
}
},
),
],
);
},
);
}
最後に
個人的にはRemoteConfigよりもFirestoreの方がシンプルに実装できると感じました!
参考になれば幸いです。
参考資料など
Discussion