Firebaseコンソールで設定した値を、
Flutterアプリから取得できるRemote Config
Remote Configとpackage_info_plusをつかって、
強制アップデート機能を実装したときの備忘録(*´ω`*)
状態管理には、riverpodを利用してる
ざっくりとした流れ
流れとしてはこんな感じ
- 起動時
- package_info_plusでバージョンなどを取得
- Remote Configで値の変更をliten開始
- Remote Configの値変更時
- 現在のバージョンと比較
- アップデートが必要であれば、ダイアログなどを出す
起動時
PackageInfo周りはこんな感じ。
import 'package:package_info_plus/package_info_plus.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; // キャッシュとして保存しておくProvider @Riverpod(keepAlive: true) PackageInfo packageInfo(PackageInfoRef ref) { throw UnimplementedError(); } // 起動時の処理 FutureOr<void> main() async { WidgetsFlutterBinding.ensureInitialized(); // パッケージ情報の取得 PackageInfo packageInfo = await PackageInfo.fromPlatform(); // Firebaseの初期化 await Firebase.initializeApp(options: options); // Firebase Remote Confingの設定 await FirebaseRemoteConfig.instance.setConfigSettings(RemoteConfigSettings( fetchTimeout: const Duration(minutes: 1), minimumFetchInterval: const Duration(minutes: 5), )); // アプリの起動 runApp(ProviderScope( overrides: [ // 初期化したinstanceで上書き packageInfoProvider.overrideWithValue(packageInfo), ], child: const MyApp(), )); }
PackageInfo
はoverrides
をつかって保持しておく
FirebaseRemoteConfigではタイムアウトと取得間隔を設定、
取得間隔(最小フェッチ間隔)のデフォルトは12時間。
Remote Configの値の変更をリアルタイムで取得/反映する
Remote Configの値を取得したり、変更を監視する部分はこんな感じ。
@Riverpod(keepAlive: true) class ForceUpdate extends _$ForceUpdate { @override bool build() { final packageInfo = ref.watch(packageInfoProvider); final remoteConfig = FirebaseRemoteConfig.instance; // リアルタイムで変更を監視 fbConfig.onConfigUpdated.listen((event) async { try { // 更新された値を反映する await remoteConfig.activate(); // バージョンを比較して、結果を保存 state = checkForceUpdate(packageInfo.version); } catch (error) { // エラーが発生したら、なにもしない } }); // 初期化時に、現在の値を取得をリクエスト remoteConfig.fetch(); // バージョンを比較して、結果を保存 return checkForceUpdate(packageInfo.version); } } // 強制アップデートが必要かどうかのチェック bool checkForceUpdate(String pkgVer) { try { // RemoteConfigの値を取得 final remoteConfig = FirebaseRemoteConfig.instance; final updateVersionKey = "update_version"; final confVer = remoteConfig.getString(updateVersionKey); if (confVer.isEmpty) return false; // packageInfo.versionと値を比較 // 強制アップデートの必要があるかを返す final result = pkgVer.compareTo(confVer) < 0; return result; } catch (error) { // エラーが発生したら、falseを返す return false; } }
Remote Configには、fetch
とactivate
の2つの動作があり、
fetch
... サーバから最新の値を取得activate
...fetch
した値を利用できるようにする
という感じ。
onConfigUpdated
では、fetch
のみなので、
activate()
で取得した値を反映後に、
remoteConfig.getString(updateVersionKey)
で値を取得している
強制アップデートの必要かの確認
あとは、対象の画面でチェックして、
ダイアログを表示しておけばOK(*´ω`*)
class FooPage extends HookConsumerWidget { const FooPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { useEffect(() { WidgetsBinding.instance.addPostFrameCallback((_) { final needUpdate = ref.read(forceUpdateProvider); if (needUpdate) { // ダイアログを表示する } }); return null; }, const []); } }
以上!! Remote Config、便利だね(*´ω`*)