Fixed remote config initalization

This commit is contained in:
Vadim 2023-11-09 16:12:57 +01:00
parent a7e75025dd
commit e5961118b0
3 changed files with 51 additions and 5 deletions

View file

@ -30,7 +30,7 @@ class ApplicationWrapper extends StatelessWidget {
future: Future.wait<dynamic>([ future: Future.wait<dynamic>([
SharedPreferences.getInstance(), SharedPreferences.getInstance(),
const LightSensorService(LocalPlatform()).hasSensor(), const LightSensorService(LocalPlatform()).hasSensor(),
const RemoteConfigService().activeAndFetchFeatures(), if (env.buildType != BuildType.dev) const RemoteConfigService().activeAndFetchFeatures(),
]), ]),
builder: (_, snapshot) { builder: (_, snapshot) {
if (snapshot.data != null) { if (snapshot.data != null) {
@ -47,7 +47,8 @@ class ApplicationWrapper extends StatelessWidget {
userPreferencesService: userPreferencesService, userPreferencesService: userPreferencesService,
volumeEventsService: const VolumeEventsService(LocalPlatform()), volumeEventsService: const VolumeEventsService(LocalPlatform()),
child: RemoteConfigProvider( child: RemoteConfigProvider(
remoteConfigService: const RemoteConfigService(), remoteConfigService:
env.buildType != BuildType.dev ? const RemoteConfigService() : const MockRemoteConfigService(),
child: EquipmentProfileProvider( child: EquipmentProfileProvider(
storageService: iapService, storageService: iapService,
child: FilmsProvider( child: FilmsProvider(

View file

@ -7,9 +7,26 @@ import 'package:firebase_remote_config/firebase_remote_config.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:lightmeter/data/models/feature.dart'; import 'package:lightmeter/data/models/feature.dart';
class RemoteConfigService { abstract class IRemoteConfigService {
const IRemoteConfigService();
Future<void> activeAndFetchFeatures();
Future<void> fetchConfig();
dynamic getValue(Feature feature);
Map<Feature, dynamic> getAll();
Stream<Set<Feature>> onConfigUpdated();
bool isEnabled(Feature feature);
}
class RemoteConfigService implements IRemoteConfigService {
const RemoteConfigService(); const RemoteConfigService();
@override
Future<void> activeAndFetchFeatures() async { Future<void> activeAndFetchFeatures() async {
final FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.instance; final FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.instance;
const cacheStaleDuration = kDebugMode ? Duration(minutes: 1) : Duration(hours: 12); const cacheStaleDuration = kDebugMode ? Duration(minutes: 1) : Duration(hours: 12);
@ -28,19 +45,22 @@ class RemoteConfigService {
log('Firebase remote config initialized successfully'); log('Firebase remote config initialized successfully');
} on FirebaseException catch (e) { } on FirebaseException catch (e) {
_logError('Firebase exception during Firebase Remote Config initialization: $e'); _logError('Firebase exception during Firebase Remote Config initialization: $e');
} on Exception catch (e) { } catch (e) {
_logError('Error during Firebase Remote Config initialization: $e'); _logError('Error during Firebase Remote Config initialization: $e');
} }
} }
@override
Future<void> fetchConfig() async { Future<void> fetchConfig() async {
// https://github.com/firebase/flutterfire/issues/6196#issuecomment-927751667 // https://github.com/firebase/flutterfire/issues/6196#issuecomment-927751667
await Future.delayed(const Duration(seconds: 1)); await Future.delayed(const Duration(seconds: 1));
await FirebaseRemoteConfig.instance.fetch(); await FirebaseRemoteConfig.instance.fetch();
} }
@override
dynamic getValue(Feature feature) => FirebaseRemoteConfig.instance.getValue(feature.name).toValue(feature); dynamic getValue(Feature feature) => FirebaseRemoteConfig.instance.getValue(feature.name).toValue(feature);
@override
Map<Feature, dynamic> getAll() { Map<Feature, dynamic> getAll() {
final Map<Feature, dynamic> result = {}; final Map<Feature, dynamic> result = {};
for (final value in FirebaseRemoteConfig.instance.getAll().entries) { for (final value in FirebaseRemoteConfig.instance.getAll().entries) {
@ -54,6 +74,7 @@ class RemoteConfigService {
return result; return result;
} }
@override
Stream<Set<Feature>> onConfigUpdated() => FirebaseRemoteConfig.instance.onConfigUpdated.asyncMap( Stream<Set<Feature>> onConfigUpdated() => FirebaseRemoteConfig.instance.onConfigUpdated.asyncMap(
(event) async { (event) async {
await FirebaseRemoteConfig.instance.activate(); await FirebaseRemoteConfig.instance.activate();
@ -69,6 +90,7 @@ class RemoteConfigService {
}, },
); );
@override
bool isEnabled(Feature feature) => FirebaseRemoteConfig.instance.getBool(feature.name); bool isEnabled(Feature feature) => FirebaseRemoteConfig.instance.getBool(feature.name);
void _logError(dynamic throwable, {StackTrace? stackTrace}) { void _logError(dynamic throwable, {StackTrace? stackTrace}) {
@ -76,6 +98,29 @@ class RemoteConfigService {
} }
} }
class MockRemoteConfigService implements IRemoteConfigService {
const MockRemoteConfigService();
@override
Future<void> activeAndFetchFeatures() async {}
@override
Future<void> fetchConfig() async {}
@override
Map<Feature, dynamic> 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<Set<Feature>> onConfigUpdated() => const Stream.empty();
}
extension on RemoteConfigValue { extension on RemoteConfigValue {
dynamic toValue(Feature feature) { dynamic toValue(Feature feature) {
switch (feature) { switch (feature) {

View file

@ -6,7 +6,7 @@ import 'package:lightmeter/data/models/feature.dart';
import 'package:lightmeter/data/remote_config_service.dart'; import 'package:lightmeter/data/remote_config_service.dart';
class RemoteConfigProvider extends StatefulWidget { class RemoteConfigProvider extends StatefulWidget {
final RemoteConfigService remoteConfigService; final IRemoteConfigService remoteConfigService;
final Widget child; final Widget child;
const RemoteConfigProvider({ const RemoteConfigProvider({