diff --git a/lib/application_wrapper.dart b/lib/application_wrapper.dart index d28fbcf..ae7d1ae 100644 --- a/lib/application_wrapper.dart +++ b/lib/application_wrapper.dart @@ -30,7 +30,7 @@ class ApplicationWrapper extends StatelessWidget { future: Future.wait([ SharedPreferences.getInstance(), const LightSensorService(LocalPlatform()).hasSensor(), - const RemoteConfigService().activeAndFetchFeatures(), + if (env.buildType != BuildType.dev) const RemoteConfigService().activeAndFetchFeatures(), ]), builder: (_, snapshot) { if (snapshot.data != null) { @@ -47,7 +47,8 @@ class ApplicationWrapper extends StatelessWidget { userPreferencesService: userPreferencesService, volumeEventsService: const VolumeEventsService(LocalPlatform()), child: RemoteConfigProvider( - remoteConfigService: const RemoteConfigService(), + remoteConfigService: + env.buildType != BuildType.dev ? const RemoteConfigService() : const MockRemoteConfigService(), child: EquipmentProfileProvider( storageService: iapService, child: FilmsProvider( diff --git a/lib/data/remote_config_service.dart b/lib/data/remote_config_service.dart index 8243dd2..f8c123b 100644 --- a/lib/data/remote_config_service.dart +++ b/lib/data/remote_config_service.dart @@ -7,9 +7,26 @@ import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:flutter/foundation.dart'; import 'package:lightmeter/data/models/feature.dart'; -class RemoteConfigService { +abstract class IRemoteConfigService { + const IRemoteConfigService(); + + Future activeAndFetchFeatures(); + + Future fetchConfig(); + + dynamic getValue(Feature feature); + + Map getAll(); + + Stream> onConfigUpdated(); + + bool isEnabled(Feature feature); +} + +class RemoteConfigService implements IRemoteConfigService { const RemoteConfigService(); + @override Future activeAndFetchFeatures() async { final FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.instance; const cacheStaleDuration = kDebugMode ? Duration(minutes: 1) : Duration(hours: 12); @@ -28,19 +45,22 @@ class RemoteConfigService { log('Firebase remote config initialized successfully'); } on FirebaseException catch (e) { _logError('Firebase exception during Firebase Remote Config initialization: $e'); - } on Exception catch (e) { + } catch (e) { _logError('Error during Firebase Remote Config initialization: $e'); } } + @override Future fetchConfig() async { // https://github.com/firebase/flutterfire/issues/6196#issuecomment-927751667 await Future.delayed(const Duration(seconds: 1)); await FirebaseRemoteConfig.instance.fetch(); } + @override dynamic getValue(Feature feature) => FirebaseRemoteConfig.instance.getValue(feature.name).toValue(feature); + @override Map getAll() { final Map result = {}; for (final value in FirebaseRemoteConfig.instance.getAll().entries) { @@ -54,6 +74,7 @@ class RemoteConfigService { return result; } + @override Stream> onConfigUpdated() => FirebaseRemoteConfig.instance.onConfigUpdated.asyncMap( (event) async { await FirebaseRemoteConfig.instance.activate(); @@ -69,6 +90,7 @@ class RemoteConfigService { }, ); + @override bool isEnabled(Feature feature) => FirebaseRemoteConfig.instance.getBool(feature.name); void _logError(dynamic throwable, {StackTrace? stackTrace}) { @@ -76,6 +98,29 @@ class RemoteConfigService { } } +class MockRemoteConfigService implements IRemoteConfigService { + const MockRemoteConfigService(); + + @override + Future activeAndFetchFeatures() async {} + + @override + Future fetchConfig() async {} + + @override + Map getAll() => featuresDefaultValues; + + @override + dynamic getValue(Feature feature) => featuresDefaultValues[feature]; + + @override + // ignore: cast_nullable_to_non_nullable + bool isEnabled(Feature feature) => featuresDefaultValues[feature] as bool; + + @override + Stream> onConfigUpdated() => const Stream.empty(); +} + extension on RemoteConfigValue { dynamic toValue(Feature feature) { switch (feature) { diff --git a/lib/providers/remote_config_provider.dart b/lib/providers/remote_config_provider.dart index a00b385..4557ed6 100644 --- a/lib/providers/remote_config_provider.dart +++ b/lib/providers/remote_config_provider.dart @@ -6,7 +6,7 @@ import 'package:lightmeter/data/models/feature.dart'; import 'package:lightmeter/data/remote_config_service.dart'; class RemoteConfigProvider extends StatefulWidget { - final RemoteConfigService remoteConfigService; + final IRemoteConfigService remoteConfigService; final Widget child; const RemoteConfigProvider({