From 0240a8df5bd490483170bef491490471d45b8775 Mon Sep 17 00:00:00 2001 From: naipaka Date: Sun, 12 Nov 2023 12:39:57 +0900 Subject: [PATCH 1/5] fix: activateAndRefetch method to call activate() instead of fetchAndActivate() --- .../lib/src/remote_parameter_fetcher.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart index 2d51a2b..74b390f 100644 --- a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart +++ b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart @@ -111,7 +111,7 @@ class RemoteParameterFetcher { (config) => config.updatedKeys.contains(key), ), activateAndRefetch: () async { - await fetchAndActivate(); + await activate(); return getString(key); }, ); @@ -125,7 +125,7 @@ class RemoteParameterFetcher { (config) => config.updatedKeys.contains(key), ), activateAndRefetch: () async { - await fetchAndActivate(); + await activate(); return getInt(key); }, ); @@ -139,7 +139,7 @@ class RemoteParameterFetcher { (config) => config.updatedKeys.contains(key), ), activateAndRefetch: () async { - await fetchAndActivate(); + await activate(); return getDouble(key); }, ); @@ -153,7 +153,7 @@ class RemoteParameterFetcher { (config) => config.updatedKeys.contains(key), ), activateAndRefetch: () async { - await fetchAndActivate(); + await activate(); return getBool(key); }, ); @@ -167,7 +167,7 @@ class RemoteParameterFetcher { (config) => config.updatedKeys.contains(key), ), activateAndRefetch: () async { - await fetchAndActivate(); + await activate(); return getJson(key); }, ); @@ -181,7 +181,7 @@ class RemoteParameterFetcher { (config) => config.updatedKeys.contains(key), ), activateAndRefetch: () async { - await fetchAndActivate(); + await activate(); return getListJson(key); }, ); @@ -198,7 +198,7 @@ class RemoteParameterFetcher { (config) => config.updatedKeys.contains(key), ), activateAndRefetch: () async { - await fetchAndActivate(); + await activate(); return getData(key: key, fromJson: fromJson); }, ); From ada9fab945d1a2c0c56035376088d18e369be5dd Mon Sep 17 00:00:00 2001 From: naipaka Date: Sun, 12 Nov 2023 12:52:54 +0900 Subject: [PATCH 2/5] fix: Refactor onConfigUpdated to Property for Consistent Stream Instance --- .../lib/src/remote_parameter_fetcher.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart index 74b390f..2fc97c7 100644 --- a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart +++ b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart @@ -49,10 +49,13 @@ class RemoteParameterFetcher { } /// Provide a Stream of updated parameter information. + /// + /// NOTE: In the method form, each call inadvertently creates + /// a different Stream, resulting in only the latest one being functional. + /// To address this issue, we use a property form to ensure a unique and + /// consistent Stream for each instance. @visibleForTesting - Stream get onConfigUpdated { - return _rc.onConfigUpdated; - } + late final Stream onConfigUpdated = _rc.onConfigUpdated; @visibleForTesting String getString(String key) { From cdee8dc281d70d9a90bf422b0891dea6a7d8eee0 Mon Sep 17 00:00:00 2001 From: naipaka Date: Sun, 12 Nov 2023 13:56:30 +0900 Subject: [PATCH 3/5] refactor: Refactor RemoteParameterFetcher to use RemoteParameter class --- .../example/lib/main.dart | 35 ++-- .../lib/remote_parameter_fetcher.dart | 1 + .../lib/src/remote_parameter.dart | 53 +----- .../lib/src/remote_parameter_fetcher.dart | 105 ++++++----- .../src/remote_parameter_fetcher_test.dart | 174 ++++++++++++++++-- .../test/src/remote_parameter_test.dart | 83 +++------ 6 files changed, 258 insertions(+), 193 deletions(-) diff --git a/packages/flutterfire_remote_parameter_fetcher/example/lib/main.dart b/packages/flutterfire_remote_parameter_fetcher/example/lib/main.dart index 9de54b5..355699b 100644 --- a/packages/flutterfire_remote_parameter_fetcher/example/lib/main.dart +++ b/packages/flutterfire_remote_parameter_fetcher/example/lib/main.dart @@ -27,26 +27,26 @@ class MainApp extends StatefulWidget { class _MainAppState extends State { late final rpf = widget.rpf; - late final _intRemoteParameter = rpf.getIntParameter('int_parameter'); + late RemoteParameter _intRemoteParameter; late int _intParameterValue; - void listen(int value) { - debugPrint('remoteParameter value changed: $value'); - _intParameterValue = value; - } - @override void initState() { super.initState(); + _intRemoteParameter = rpf.getIntParameter( + 'int_parameter', + onConfigUpdated: (value) { + debugPrint('remoteParameter value changed: $value'); + _intParameterValue = value; + }, + ); _intParameterValue = _intRemoteParameter.value; - _intRemoteParameter.addListener(listen); } @override - void dispose() { - // TODO(riscait): adding - // remoteParameter.removeListener(listen); + Future dispose() async { + await _intRemoteParameter.dispose(); super.dispose(); } @@ -57,19 +57,8 @@ class _MainAppState extends State { appBar: AppBar(title: const Text('FlutterFireRemoteParameterFetcher')), body: Padding( padding: const EdgeInsets.all(32), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Text('RemoteParameter value: $_intParameterValue'), - const SizedBox(height: 16), - FilledButton( - onPressed: () async { - await _intRemoteParameter.activateAndRefetch(); - }, - child: const Text('Activate and refetch'), - ), - ], + child: Center( + child: Text('RemoteParameter value: $_intParameterValue'), ), ), ), diff --git a/packages/flutterfire_remote_parameter_fetcher/lib/remote_parameter_fetcher.dart b/packages/flutterfire_remote_parameter_fetcher/lib/remote_parameter_fetcher.dart index a032160..57c305c 100644 --- a/packages/flutterfire_remote_parameter_fetcher/lib/remote_parameter_fetcher.dart +++ b/packages/flutterfire_remote_parameter_fetcher/lib/remote_parameter_fetcher.dart @@ -1,4 +1,5 @@ /// Remote Parameter Fetcher library remote_parameter_fetcher; +export '../src/remote_parameter.dart'; export '../src/remote_parameter_fetcher.dart'; diff --git a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter.dart b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter.dart index bcab48c..474f87e 100644 --- a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter.dart +++ b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter.dart @@ -5,54 +5,19 @@ import 'dart:async'; class RemoteParameter { RemoteParameter({ required T value, - required this.onConfigUpdated, - required this.activateAndRefetch, - }) : _value = value; + required StreamSubscription subscription, + }) : _value = value, + _subscription = subscription; - /// A Stream of updated parameter information. - Stream onConfigUpdated; - - /// A function that will activate the fetched config and refetch the value. - /// This is useful for when you want to force a refetch of the value. - final Future Function() activateAndRefetch; + /// The subscription to the stream of updated parameter information. + final StreamSubscription _subscription; /// The current value of the parameter. T get value => _value; - T _value; - - final List _listeners = []; - - late StreamSubscription _subscription; - - /// Add a listener to be notified when the value changes. - /// Executed when the remote value is updated. - void addListener(void Function(T value) listener) { - _listeners.add(listener); - - if (_listeners.length == 1) { - // When the listener is added for the first time, - // monitor the onConfigUpdated stream. - _subscription = onConfigUpdated.listen((_) async { - _value = await activateAndRefetch(); - _notifyListeners(); - }); - } - } - - /// Remove a listener. - Future removeListener(void Function(T value) listener) async { - _listeners.remove(listener); - - if (_listeners.isEmpty) { - // When the last listener is removed, - // cancel the subscription to the onConfigUpdated stream. - await _subscription.cancel(); - } - } + final T _value; - void _notifyListeners() { - for (final listener in _listeners) { - listener(_value); - } + /// Closes the [RemoteParameter]. + Future dispose() async { + await _subscription.cancel(); } } diff --git a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart index 2fc97c7..b980649 100644 --- a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart +++ b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart @@ -5,6 +5,8 @@ import 'package:meta/meta.dart'; import 'remote_parameter.dart'; +typedef ValueChanged = void Function(T value); + /// A class that wraps Remote Config. /// Its role is to "fetch the configured parameters from remote and provide /// them". @@ -57,6 +59,11 @@ class RemoteParameterFetcher { @visibleForTesting late final Stream onConfigUpdated = _rc.onConfigUpdated; + /// Filter the Stream of updated parameter information by key. + Stream filteredOnConfigUpdated(String key) { + return onConfigUpdated.where((config) => config.updatedKeys.contains(key)); + } + @visibleForTesting String getString(String key) { final value = _rc.getString(key); @@ -107,103 +114,101 @@ class RemoteParameterFetcher { } /// Returns a [RemoteParameter] of type [String]. - RemoteParameter getStringParameter(String key) { + RemoteParameter getStringParameter( + String key, { + required ValueChanged onConfigUpdated, + }) { return RemoteParameter( value: getString(key), - onConfigUpdated: onConfigUpdated.where( - (config) => config.updatedKeys.contains(key), - ), - activateAndRefetch: () async { + subscription: filteredOnConfigUpdated(key).listen((event) async { await activate(); - return getString(key); - }, + onConfigUpdated(getString(key)); + }), ); } /// Returns a [RemoteParameter] of type [int]. - RemoteParameter getIntParameter(String key) { + RemoteParameter getIntParameter( + String key, { + required ValueChanged onConfigUpdated, + }) { return RemoteParameter( value: getInt(key), - onConfigUpdated: onConfigUpdated.where( - (config) => config.updatedKeys.contains(key), - ), - activateAndRefetch: () async { + subscription: filteredOnConfigUpdated(key).listen((event) async { await activate(); - return getInt(key); - }, + onConfigUpdated(getInt(key)); + }), ); } /// Returns a [RemoteParameter] of type [double]. - RemoteParameter getDoubleParameter(String key) { + RemoteParameter getDoubleParameter( + String key, { + required ValueChanged onConfigUpdated, + }) { return RemoteParameter( value: getDouble(key), - onConfigUpdated: onConfigUpdated.where( - (config) => config.updatedKeys.contains(key), - ), - activateAndRefetch: () async { + subscription: filteredOnConfigUpdated(key).listen((event) async { await activate(); - return getDouble(key); - }, + onConfigUpdated(getDouble(key)); + }), ); } /// Returns a [RemoteParameter] of type [bool]. - RemoteParameter getBoolParameter(String key) { + RemoteParameter getBoolParameter( + String key, { + required ValueChanged onConfigUpdated, + }) { return RemoteParameter( value: getBool(key), - onConfigUpdated: onConfigUpdated.where( - (config) => config.updatedKeys.contains(key), - ), - activateAndRefetch: () async { + subscription: filteredOnConfigUpdated(key).listen((event) async { await activate(); - return getBool(key); - }, + onConfigUpdated(getBool(key)); + }), ); } /// Returns a [RemoteParameter] of type [Map]. - RemoteParameter> getJsonParameter(String key) { + RemoteParameter> getJsonParameter( + String key, { + required void Function(Map value) onConfigUpdated, + }) { return RemoteParameter>( value: getJson(key), - onConfigUpdated: onConfigUpdated.where( - (config) => config.updatedKeys.contains(key), - ), - activateAndRefetch: () async { + subscription: filteredOnConfigUpdated(key).listen((event) async { await activate(); - return getJson(key); - }, + onConfigUpdated(getJson(key)); + }), ); } /// Returns a [RemoteParameter] of type [List] of [Map]. - RemoteParameter>> getListJsonParameter(String key) { + RemoteParameter>> getListJsonParameter( + String key, { + required ValueChanged>> onConfigUpdated, + }) { return RemoteParameter>>( value: getListJson(key), - onConfigUpdated: onConfigUpdated.where( - (config) => config.updatedKeys.contains(key), - ), - activateAndRefetch: () async { + subscription: filteredOnConfigUpdated(key).listen((event) async { await activate(); - return getListJson(key); - }, + onConfigUpdated(getListJson(key)); + }), ); } /// Returns a [RemoteParameter] of type [T]. - RemoteParameter getDataParameter({ - required String key, + RemoteParameter getDataParameter( + String key, { required T Function(Map) fromJson, + required ValueChanged onConfigUpdated, }) { return RemoteParameter( value: getData(key: key, fromJson: fromJson), - onConfigUpdated: onConfigUpdated.where( - (config) => config.updatedKeys.contains(key), - ), - activateAndRefetch: () async { + subscription: filteredOnConfigUpdated(key).listen((event) async { await activate(); - return getData(key: key, fromJson: fromJson); - }, + onConfigUpdated(getData(key: key, fromJson: fromJson)); + }), ); } } diff --git a/packages/flutterfire_remote_parameter_fetcher/test/src/remote_parameter_fetcher_test.dart b/packages/flutterfire_remote_parameter_fetcher/test/src/remote_parameter_fetcher_test.dart index 5397b03..7b937c4 100644 --- a/packages/flutterfire_remote_parameter_fetcher/test/src/remote_parameter_fetcher_test.dart +++ b/packages/flutterfire_remote_parameter_fetcher/test/src/remote_parameter_fetcher_test.dart @@ -3,7 +3,6 @@ import 'dart:async'; import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutterfire_remote_parameter_fetcher/remote_parameter_fetcher.dart'; -import 'package:flutterfire_remote_parameter_fetcher/src/remote_parameter.dart'; import '../data_class.dart'; @@ -55,6 +54,19 @@ void main() { }); }); + group('filteredOnConfigUpdated', () { + test('Can retrieve the Stream of RemoteConfigUpdate filtered by key', + () async { + final mockRC = _FakeRemoteConfig(); + final target = RemoteParameterFetcher(rc: mockRC); + + const key = 'string_001'; + + final stream = target.filteredOnConfigUpdated(key); + expect(stream, isA>()); + }); + }); + group('getString', () { test('Can retrieve the Remote string corresponding to the key', () { final mockRC = _FakeRemoteConfig(); @@ -167,16 +179,30 @@ void main() { group('getStringParameter', () { test( 'Can retrieve the RemoteParameter corresponding to the key', - () { + () async { final mockRC = _FakeRemoteConfig(); final target = RemoteParameterFetcher(rc: mockRC); const key = 'string_001'; + var updatedValue = ''; - final value = target.getStringParameter(key); + final parameter = target.getStringParameter( + key, + onConfigUpdated: (value) { + updatedValue = value; + }, + ); + + expect(parameter, isA>()); + expect(parameter.value, equals('string_value')); + + mockRC.configUpdatesController.add( + RemoteConfigUpdate({key}), + ); + + await pumpEventQueue(); - expect(value, isA>()); - expect(value.value, equals('string_value')); + expect(updatedValue, equals('string_value')); }, ); }); @@ -184,16 +210,30 @@ void main() { group('getIntParameter', () { test( 'Can retrieve the RemoteParameter corresponding to the key', - () { + () async { final mockRC = _FakeRemoteConfig(); final target = RemoteParameterFetcher(rc: mockRC); const key = 'int_001'; + var updatedValue = 0; - final value = target.getIntParameter(key); + final value = target.getIntParameter( + key, + onConfigUpdated: (value) { + updatedValue = value; + }, + ); expect(value, isA>()); expect(value.value, equals(1)); + + mockRC.configUpdatesController.add( + RemoteConfigUpdate({key}), + ); + + await pumpEventQueue(); + + expect(updatedValue, equals(1)); }, ); }); @@ -201,16 +241,30 @@ void main() { group('getDoubleParameter', () { test( 'Can retrieve the RemoteParameter corresponding to the key', - () { + () async { final mockRC = _FakeRemoteConfig(); final target = RemoteParameterFetcher(rc: mockRC); const key = 'double_001'; + var updatedValue = 0.0; - final value = target.getDoubleParameter(key); + final value = target.getDoubleParameter( + key, + onConfigUpdated: (value) { + updatedValue = value; + }, + ); expect(value, isA>()); expect(value.value, equals(0.1)); + + mockRC.configUpdatesController.add( + RemoteConfigUpdate({key}), + ); + + await pumpEventQueue(); + + expect(updatedValue, equals(0.1)); }, ); }); @@ -218,16 +272,30 @@ void main() { group('getBoolParameter', () { test( 'Can retrieve the RemoteParameter corresponding to the key', - () { + () async { final mockRC = _FakeRemoteConfig(); final target = RemoteParameterFetcher(rc: mockRC); const key = 'bool_001'; + var updatedValue = false; - final value = target.getBoolParameter(key); + final value = target.getBoolParameter( + key, + onConfigUpdated: (value) { + updatedValue = value; + }, + ); expect(value, isA>()); expect(value.value, isTrue); + + mockRC.configUpdatesController.add( + RemoteConfigUpdate({key}), + ); + + await pumpEventQueue(); + + expect(updatedValue, isTrue); }, ); }); @@ -236,13 +304,19 @@ void main() { test( 'Can retrieve the RemoteParameter> ' 'corresponding to the key', - () { + () async { final mockRC = _FakeRemoteConfig(); final target = RemoteParameterFetcher(rc: mockRC); const key = 'json_001'; + var updatedValue = {}; - final value = target.getJsonParameter(key); + final value = target.getJsonParameter( + key, + onConfigUpdated: (value) { + updatedValue = value; + }, + ); expect(value, isA>>()); expect(value.value, { @@ -251,6 +325,19 @@ void main() { 'value_3': 3.0, 'value_4': true, }); + + mockRC.configUpdatesController.add( + RemoteConfigUpdate({key}), + ); + + await pumpEventQueue(); + + expect(updatedValue, { + 'value_1': '01', + 'value_2': 2, + 'value_3': 3.0, + 'value_4': true, + }); }, ); }); @@ -259,13 +346,19 @@ void main() { test( 'Can retrieve the RemoteParameter>> ' 'corresponding to the key', - () { + () async { final mockRC = _FakeRemoteConfig(); final target = RemoteParameterFetcher(rc: mockRC); const key = 'list_json_001'; + var updatedValue = >[]; - final value = target.getListJsonParameter(key); + final value = target.getListJsonParameter( + key, + onConfigUpdated: (value) { + updatedValue = value; + }, + ); expect(value, isA>>>()); expect( @@ -285,6 +378,30 @@ void main() { } ], ); + + mockRC.configUpdatesController.add( + RemoteConfigUpdate({key}), + ); + + await pumpEventQueue(); + + expect( + updatedValue, + [ + { + 'value_1a': '01a', + 'value_2a': 2, + 'value_3a': 3.0, + 'value_4a': true, + }, + { + 'value_1b': '01b', + 'value_2b': 20, + 'value_3b': 3.5, + 'value_4b': false, + } + ], + ); }, ); }); @@ -292,30 +409,42 @@ void main() { group('getDataParameter', () { test( 'Can retrieve the RemoteParameter corresponding to the key', - () { + () async { final mockRC = _FakeRemoteConfig(); final target = RemoteParameterFetcher(rc: mockRC); const key = 'data_001'; + var updatedValue = const DataClass(value: ''); final value = target.getDataParameter( - key: key, + key, fromJson: DataClass.fromJson, + onConfigUpdated: (value) { + updatedValue = value; + }, ); expect(value, isA>()); expect(value.value, const DataClass(value: 'tokyo')); + + mockRC.configUpdatesController.add( + RemoteConfigUpdate({key}), + ); + + await pumpEventQueue(); + + expect(updatedValue, const DataClass(value: 'tokyo')); }, ); }); } class _FakeRemoteConfig extends Fake implements FirebaseRemoteConfig { - final _configUpdatesController = StreamController(); + final configUpdatesController = StreamController(); @override Stream get onConfigUpdated => - _configUpdatesController.stream; + configUpdatesController.stream; @override String getString(String key) { @@ -376,7 +505,12 @@ class _FakeRemoteConfig extends Fake implements FirebaseRemoteConfig { return true; } + @override + Future activate() async { + return true; + } + void dispose() { - unawaited(_configUpdatesController.close()); + unawaited(configUpdatesController.close()); } } diff --git a/packages/flutterfire_remote_parameter_fetcher/test/src/remote_parameter_test.dart b/packages/flutterfire_remote_parameter_fetcher/test/src/remote_parameter_test.dart index 73b2a44..2aa7b4d 100644 --- a/packages/flutterfire_remote_parameter_fetcher/test/src/remote_parameter_test.dart +++ b/packages/flutterfire_remote_parameter_fetcher/test/src/remote_parameter_test.dart @@ -6,83 +6,54 @@ import 'package:flutterfire_remote_parameter_fetcher/src/remote_parameter.dart'; void main() { group('RemoteParameter', () { test('should initialize with correct value', () async { - final rp = RemoteParameter( - value: 10, - onConfigUpdated: const Stream.empty(), - activateAndRefetch: () async => 10, - ); - - expect(rp.value, 10); - }); - - test('should call listener when value changes', () async { final controller = StreamController(); addTearDown(controller.close); - final rp = RemoteParameter( value: 10, - onConfigUpdated: controller.stream, - activateAndRefetch: () async => 20, + subscription: controller.stream.listen((event) {}), ); - int? updatedValue; - rp.addListener((value) { - updatedValue = value; - }); - - controller.add(null); - - await Future.delayed(Duration.zero); - - expect(updatedValue, 20); - expect(rp.value, 20); + expect(rp.value, 10); }); - test('should not call listener when removed', () async { - final controller = StreamController(); + test('should update value when stream emits', () async { + final controller = StreamController(); addTearDown(controller.close); - - final rp = RemoteParameter( - value: 10, - onConfigUpdated: controller.stream, - activateAndRefetch: () async => 20, + var value = 10; + RemoteParameter( + value: value, + subscription: controller.stream.listen((event) { + value = event; + }), ); - var updatedValue = 10; - void listener(int value) { - updatedValue = value; - } + controller.add(20); - rp.addListener(listener); + await pumpEventQueue(); - await rp.removeListener(listener); - controller.add(null); - await Future.delayed(Duration.zero); - - expect(rp.value, 10); - expect(updatedValue, 10); + expect(value, 20); }); - test('should refetch value when config updates', () async { - final controller = StreamController(); + test('should close subscription when dispose is called', () async { + final controller = StreamController(); addTearDown(controller.close); - - var refetchCalled = false; + var value = 10; final rp = RemoteParameter( value: 10, - onConfigUpdated: controller.stream, - activateAndRefetch: () async { - refetchCalled = true; - return 20; - }, - )..addListener((_) {}); + subscription: controller.stream.listen((event) { + value = event; + }), + ); - controller.add(null); + controller.add(20); + await pumpEventQueue(); + expect(value, 20); - await Future.delayed(Duration.zero); + await rp.dispose(); - expect(refetchCalled, true); - expect(rp.value, 20); + controller.add(30); + await pumpEventQueue(); + expect(value, 20); }); }); } From c78444031142ecc6b56f5254251884532d11d4a7 Mon Sep 17 00:00:00 2001 From: naipaka Date: Sun, 12 Nov 2023 14:08:50 +0900 Subject: [PATCH 4/5] fix: Fix remote_parameter_fetcher example --- .../example/lib/main.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/flutterfire_remote_parameter_fetcher/example/lib/main.dart b/packages/flutterfire_remote_parameter_fetcher/example/lib/main.dart index 355699b..41d25cc 100644 --- a/packages/flutterfire_remote_parameter_fetcher/example/lib/main.dart +++ b/packages/flutterfire_remote_parameter_fetcher/example/lib/main.dart @@ -38,7 +38,9 @@ class _MainAppState extends State { 'int_parameter', onConfigUpdated: (value) { debugPrint('remoteParameter value changed: $value'); - _intParameterValue = value; + setState(() { + _intParameterValue = value; + }); }, ); _intParameterValue = _intRemoteParameter.value; From 2ed9fdbd2cbf87e766855847c6ed3a5b8ef74ff8 Mon Sep 17 00:00:00 2001 From: Ryota Kobayashi <45661924+naipaka@users.noreply.github.com> Date: Sun, 12 Nov 2023 15:34:00 +0900 Subject: [PATCH 5/5] refactor: Implement Use of ValueChanged Co-authored-by: Ryunosuke Muramatsu --- .../lib/src/remote_parameter_fetcher.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart index b980649..4a1f5c9 100644 --- a/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart +++ b/packages/flutterfire_remote_parameter_fetcher/lib/src/remote_parameter_fetcher.dart @@ -172,7 +172,7 @@ class RemoteParameterFetcher { /// Returns a [RemoteParameter] of type [Map]. RemoteParameter> getJsonParameter( String key, { - required void Function(Map value) onConfigUpdated, + required ValueChanged> onConfigUpdated, }) { return RemoteParameter>( value: getJson(key),