[{"data":1,"prerenderedAt":69},["ShallowReactive",2],{"tutorial-autenticazione-con-firebase-authentication-in-flutter-login-email-e-password":3,"comments-tutorial-autenticazione-con-firebase-authentication-in-flutter-login-email-e-password":68},{"id":4,"title":5,"slug":6,"excerpt":7,"intro":8,"cover_image":9,"video_url":10,"difficulty":11,"estimated_minutes":12,"flutter_version":13,"status":14,"published_at":15,"meta_title":16,"meta_description":17,"category":18,"author":22,"steps":24},21,"Autenticazione con Firebase Authentication in Flutter: login email e password","autenticazione-con-firebase-authentication-in-flutter-login-email-e-password","Impara a integrare Firebase Authentication in Flutter per gestire registrazione, login e logout degli utenti con email e password in modo sicuro.","# Autenticazione con Firebase Authentication\n\nQuasi ogni applicazione moderna richiede un sistema di autenticazione. **Firebase Authentication** offre una soluzione robusta, sicura e pronta all'uso che gestisce per noi la parte più complessa: hashing delle password, gestione delle sessioni e sicurezza.\n\nIn questo tutorial costruiremo un flusso completo di autenticazione con **email e password**: registrazione, login, logout e gestione reattiva dello stato dell'utente tramite uno `StreamBuilder`.\n\n> **Prerequisiti**: un progetto Flutter funzionante, un account Google e una conoscenza di base dei widget Flutter.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002F2853388a-49c5-4af9-bd84-4784c24af144.jpg",null,"intermediate",40,"3.x","published","2026-06-27T04:30:46+00:00","Firebase Authentication in Flutter: login email e password","Guida pratica per integrare Firebase Authentication in Flutter: registrazione, login, logout e gestione reattiva dello stato utente.",{"id":19,"name":20,"slug":21},1,"Guide","guide",{"id":19,"name":23},"Flutter Bot",[25,32,39,47,54,61],{"id":26,"position":19,"title":27,"body":28,"code_snippet":29,"code_language":30,"expected_result":31,"demo_url":10,"video_url":10},143,"Creare il progetto Firebase e collegarlo a Flutter","Per prima cosa creiamo un progetto sulla [Firebase Console](https:\u002F\u002Fconsole.firebase.google.com). Una volta creato, abilitiamo il metodo di accesso **Email\u002FPassword** dalla sezione *Authentication > Sign-in method*.\n\nIl modo più semplice e moderno per collegare Firebase a Flutter è usare la **FlutterFire CLI**. Installiamo gli strumenti necessari ed eseguiamo la configurazione automatica dalla cartella del progetto.\n\nLa CLI genererà automaticamente il file `firebase_options.dart` con tutte le chiavi di configurazione per le varie piattaforme.","# Installa la CLI di Firebase (se non presente)\nnpm install -g firebase-tools\nfirebase login\n\n# Installa la FlutterFire CLI\ndart pub global activate flutterfire_cli\n\n# Dalla cartella del progetto, configura Firebase\nflutterfire configure","bash","Nella cartella lib\u002F viene generato il file firebase_options.dart e Firebase è abilitato per le piattaforme selezionate.",{"id":33,"position":34,"title":35,"body":36,"code_snippet":37,"code_language":30,"expected_result":38,"demo_url":10,"video_url":10},144,2,"Aggiungere le dipendenze","Aggiungiamo i pacchetti necessari al file `pubspec.yaml`: `firebase_core` per inizializzare Firebase e `firebase_auth` per l'autenticazione.\n\nPossiamo usare il comando `flutter pub add` che inserisce automaticamente le versioni più recenti compatibili.","flutter pub add firebase_core firebase_auth","Le dipendenze firebase_core e firebase_auth compaiono nel pubspec.yaml e vengono scaricate.",{"id":40,"position":41,"title":42,"body":43,"code_snippet":44,"code_language":45,"expected_result":46,"demo_url":10,"video_url":10},145,3,"Inizializzare Firebase nel main","Prima di usare qualsiasi servizio Firebase dobbiamo inizializzarlo. Modifichiamo la funzione `main` rendendola asincrona e chiamando `Firebase.initializeApp` con le opzioni generate.\n\nÈ fondamentale chiamare `WidgetsFlutterBinding.ensureInitialized()` prima dell'inizializzazione, perché stiamo eseguendo codice asincrono prima di `runApp`.","import 'package:flutter\u002Fmaterial.dart';\nimport 'package:firebase_core\u002Ffirebase_core.dart';\nimport 'firebase_options.dart';\n\nFuture\u003Cvoid> main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  await Firebase.initializeApp(\n    options: DefaultFirebaseOptions.currentPlatform,\n  );\n  runApp(const MyApp());\n}\n\nclass MyApp extends StatelessWidget {\n  const MyApp({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      title: 'Auth Demo',\n      theme: ThemeData(useMaterial3: true),\n      home: const AuthGate(),\n    );\n  }\n}","dart","L'app si avvia senza errori e Firebase risulta correttamente inizializzato.",{"id":48,"position":49,"title":50,"body":51,"code_snippet":52,"code_language":45,"expected_result":53,"demo_url":10,"video_url":10},146,4,"Creare un servizio di autenticazione","Per mantenere il codice pulito, isoliamo la logica di Firebase in una classe `AuthService`. Questo ci permette di centralizzare i metodi di registrazione, login e logout e di gestire gli errori in modo uniforme.\n\nUsiamo `FirebaseAuth.instance` per accedere alle funzionalità e intercettiamo le `FirebaseAuthException` per restituire messaggi comprensibili all'utente.","import 'package:firebase_auth\u002Ffirebase_auth.dart';\n\nclass AuthService {\n  final FirebaseAuth _auth = FirebaseAuth.instance;\n\n  \u002F\u002F Stream che notifica i cambiamenti di stato dell'utente\n  Stream\u003CUser?> get authStateChanges => _auth.authStateChanges();\n\n  Future\u003CString?> signUp(String email, String password) async {\n    try {\n      await _auth.createUserWithEmailAndPassword(\n        email: email,\n        password: password,\n      );\n      return null; \u002F\u002F nessun errore\n    } on FirebaseAuthException catch (e) {\n      if (e.code == 'email-already-in-use') {\n        return 'Email già registrata.';\n      } else if (e.code == 'weak-password') {\n        return 'La password è troppo debole.';\n      }\n      return e.message ?? 'Errore sconosciuto.';\n    }\n  }\n\n  Future\u003CString?> signIn(String email, String password) async {\n    try {\n      await _auth.signInWithEmailAndPassword(\n        email: email,\n        password: password,\n      );\n      return null;\n    } on FirebaseAuthException catch (e) {\n      if (e.code == 'user-not-found' || e.code == 'wrong-password' || e.code == 'invalid-credential') {\n        return 'Credenziali non valide.';\n      }\n      return e.message ?? 'Errore sconosciuto.';\n    }\n  }\n\n  Future\u003Cvoid> signOut() => _auth.signOut();\n}","La classe AuthService è pronta e centralizza tutta la logica di autenticazione.",{"id":55,"position":56,"title":57,"body":58,"code_snippet":59,"code_language":45,"expected_result":60,"demo_url":10,"video_url":10},147,5,"Gestire lo stato con AuthGate e StreamBuilder","Il modo reattivo per mostrare la schermata giusta è ascoltare lo stream `authStateChanges`. Creiamo un widget `AuthGate` che, tramite uno `StreamBuilder`, mostra la `HomeScreen` se l'utente è loggato o la `LoginScreen` in caso contrario.\n\nIn questo modo l'app reagisce automaticamente a login e logout senza navigazione manuale.","import 'package:flutter\u002Fmaterial.dart';\nimport 'package:firebase_auth\u002Ffirebase_auth.dart';\n\nclass AuthGate extends StatelessWidget {\n  const AuthGate({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    return StreamBuilder\u003CUser?>(\n      stream: AuthService().authStateChanges,\n      builder: (context, snapshot) {\n        if (snapshot.connectionState == ConnectionState.waiting) {\n          return const Scaffold(\n            body: Center(child: CircularProgressIndicator()),\n          );\n        }\n        if (snapshot.hasData) {\n          return const HomeScreen();\n        }\n        return const LoginScreen();\n      },\n    );\n  }\n}\n\nclass HomeScreen extends StatelessWidget {\n  const HomeScreen({super.key});\n\n  @override\n  Widget build(BuildContext context) {\n    final user = FirebaseAuth.instance.currentUser;\n    return Scaffold(\n      appBar: AppBar(\n        title: const Text('Home'),\n        actions: [\n          IconButton(\n            icon: const Icon(Icons.logout),\n            onPressed: () => AuthService().signOut(),\n          ),\n        ],\n      ),\n      body: Center(child: Text('Benvenuto, ${user?.email ?? ''}')),\n    );\n  }\n}","All'avvio l'app mostra la LoginScreen; dopo il login passa automaticamente alla HomeScreen.",{"id":62,"position":63,"title":64,"body":65,"code_snippet":66,"code_language":45,"expected_result":67,"demo_url":10,"video_url":10},148,6,"Costruire la schermata di login e registrazione","Creiamo una `LoginScreen` con due campi (email e password) e un pulsante che alterna tra modalità login e registrazione. Validiamo i campi e mostriamo eventuali errori restituiti da `AuthService` tramite uno `SnackBar`.\n\nUsiamo uno `StatefulWidget` per gestire lo stato dei controller e l'indicatore di caricamento.","class LoginScreen extends StatefulWidget {\n  const LoginScreen({super.key});\n\n  @override\n  State\u003CLoginScreen> createState() => _LoginScreenState();\n}\n\nclass _LoginScreenState extends State\u003CLoginScreen> {\n  final _emailCtrl = TextEditingController();\n  final _passCtrl = TextEditingController();\n  final _auth = AuthService();\n  bool _isLogin = true;\n  bool _loading = false;\n\n  Future\u003Cvoid> _submit() async {\n    setState(() => _loading = true);\n    final error = _isLogin\n        ? await _auth.signIn(_emailCtrl.text.trim(), _passCtrl.text.trim())\n        : await _auth.signUp(_emailCtrl.text.trim(), _passCtrl.text.trim());\n    setState(() => _loading = false);\n    if (error != null && mounted) {\n      ScaffoldMessenger.of(context)\n          .showSnackBar(SnackBar(content: Text(error)));\n    }\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: Text(_isLogin ? 'Login' : 'Registrazione')),\n      body: Padding(\n        padding: const EdgeInsets.all(24),\n        child: Column(\n          mainAxisAlignment: MainAxisAlignment.center,\n          children: [\n            TextField(\n              controller: _emailCtrl,\n              decoration: const InputDecoration(labelText: 'Email'),\n              keyboardType: TextInputType.emailAddress,\n            ),\n            const SizedBox(height: 12),\n            TextField(\n              controller: _passCtrl,\n              decoration: const InputDecoration(labelText: 'Password'),\n              obscureText: true,\n            ),\n            const SizedBox(height: 24),\n            _loading\n                ? const CircularProgressIndicator()\n                : ElevatedButton(\n                    onPressed: _submit,\n                    child: Text(_isLogin ? 'Accedi' : 'Registrati'),\n                  ),\n            TextButton(\n              onPressed: () => setState(() => _isLogin = !_isLogin),\n              child: Text(_isLogin\n                  ? 'Non hai un account? Registrati'\n                  : 'Hai già un account? Accedi'),\n            ),\n          ],\n        ),\n      ),\n    );\n  }\n}","L'utente può registrarsi, accedere e fare logout; lo stato si aggiorna automaticamente grazie all'AuthGate.",[],1785219610952]