Cosa sono i feature flags e perché usarli
I feature flags (o feature toggles) sono interruttori che permettono di attivare o disattivare funzionalità della tua app senza rilasciare una nuova versione sugli store. Sono utili per:
- Rilasci graduali (rollout progressivo di una feature).
- A/B testing su gruppi di utenti.
- Kill switch per disattivare rapidamente una funzione problematica.
- Personalizzazione dei contenuti in base al segmento di utenza.
In Flutter, uno degli strumenti più comodi per implementarli è Firebase Remote Config, che consente di definire valori sul server e leggerli dall'app in tempo reale.
Setup del progetto
Aggiungi le dipendenze necessarie al file pubspec.yaml:
dependencies:
firebase_core: ^3.6.0
firebase_remote_config: ^5.1.3
Assicurati di aver configurato Firebase nel progetto tramite flutterfire configure. Poi inizializza Firebase nel main:
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
Configurare Remote Config
Creiamo un servizio dedicato che incapsula la logica di Remote Config. Impostiamo prima i valori di default, fondamentali per garantire un comportamento coerente quando l'app è offline o al primo avvio.
import 'package:firebase_remote_config/firebase_remote_config.dart';
class RemoteConfigService {
final FirebaseRemoteConfig _rc = FirebaseRemoteConfig.instance;
Future<void> init() async {
await _rc.setConfigSettings(
RemoteConfigSettings(
fetchTimeout: const Duration(seconds: 10),
minimumFetchInterval: const Duration(hours: 1),
),
);
// Valori di default usati finché non arriva il fetch dal server
await _rc.setDefaults(const {
'new_checkout_enabled': false,
'welcome_message': 'Benvenuto!',
'max_items_per_page': 20,
});
await _rc.fetchAndActivate();
}
bool get newCheckoutEnabled => _rc.getBool('new_checkout_enabled');
String get welcomeMessage => _rc.getString('welcome_message');
int get maxItemsPerPage => _rc.getInt('max_items_per_page');
}
minimumFetchInterval
Attenzione a minimumFetchInterval: in produzione un valore alto (es. 1 ora) evita di sovraccaricare il server e ridurre i costi. In sviluppo puoi impostarlo a Duration.zero per vedere subito le modifiche, ma ricorda che Firebase limita comunque il numero di fetch per evitare throttling.
Usare i flag nella UI
Una volta inizializzato il servizio, leggere un flag è immediato:
class CheckoutButton extends StatelessWidget {
final RemoteConfigService config;
const CheckoutButton({super.key, required this.config});
@override
Widget build(BuildContext context) {
if (config.newCheckoutEnabled) {
return const NewCheckoutFlow();
}
return const LegacyCheckoutFlow();
}
}
Aggiornamenti in tempo reale con onConfigUpdated
Remote Config supporta un listener che notifica quando i valori cambiano sul server, permettendo aggiornamenti live senza riavviare l'app:
_rc.onConfigUpdated.listen((event) async {
await _rc.activate();
// Notifica la UI, ad esempio tramite un ValueNotifier o uno stream
notifyListeners();
});
Questo è particolarmente potente per i kill switch: puoi disattivare una feature difettosa e vedere l'effetto sui dispositivi degli utenti in pochi secondi.
Integrazione con la gestione dello stato
Puoi esporre i flag tramite un ChangeNotifier o un provider per renderli reattivi. Ecco un esempio con ValueNotifier:
class FeatureFlags extends ChangeNotifier {
final RemoteConfigService _service;
FeatureFlags(this._service) {
_service.init().then((_) => notifyListeners());
}
bool get newCheckout => _service.newCheckoutEnabled;
}
Best practice
- Definisci sempre i default: garantiscono un'esperienza coerente offline e al primo avvio.
- Usa nomi di chiavi descrittivi e versionati (es.
feature_dark_mode_v2). - Non abusare dei flag: troppi toggle attivi rendono difficile testare tutte le combinazioni.
- Pulisci i flag obsoleti: una volta che una feature è stabile, rimuovi il toggle dal codice.
- Combina con Firebase A/B Testing per misurare l'impatto delle nuove funzionalità su metriche reali.
Conclusione
Firebase Remote Config offre un modo semplice e gratuito per introdurre feature flags nelle app Flutter, disaccoppiando il rilascio del codice dall'attivazione delle funzionalità. Con pochi passaggi puoi ottenere rollout controllati, A/B test e kill switch, migliorando sensibilmente la sicurezza e la flessibilità dei tuoi rilasci.
