[{"data":1,"prerenderedAt":76},["ShallowReactive",2],{"tutorial-notifiche-push-in-flutter-con-firebase-cloud-messaging":3,"comments-tutorial-notifiche-push-in-flutter-con-firebase-cloud-messaging":75},{"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":5,"meta_description":16,"category":17,"author":21,"steps":23},33,"Notifiche push in Flutter con Firebase Cloud Messaging","notifiche-push-in-flutter-con-firebase-cloud-messaging","Impara a integrare Firebase Cloud Messaging in Flutter per ricevere notifiche push in foreground, background e ad app chiusa, gestendo token e payload.","Le notifiche push sono uno strumento fondamentale per coinvolgere gli utenti anche quando l'app non è in uso. In questo tutorial integreremo **Firebase Cloud Messaging (FCM)** in un'app Flutter, imparando a configurare il progetto, ottenere il token del dispositivo e gestire i messaggi nei tre stati principali dell'app: in primo piano, in background e completamente chiusa.\n\nPartiamo dal presupposto di avere già un progetto Firebase collegato tramite FlutterFire. Vedremo anche come mostrare una notifica visibile quando l'app è in foreground, dato che FCM di default non lo fa automaticamente su Android.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Ftutorials\u002F1520e01a-9f9a-4cb9-b27a-592ceea66668.jpg",null,"intermediate",40,"3.x","published","2026-07-09T04:30:47+00:00","Guida pratica per integrare Firebase Cloud Messaging in Flutter: token, gestione messaggi in foreground, background e ad app chiusa.",{"id":18,"name":19,"slug":20},1,"Guide","guide",{"id":18,"name":22},"Flutter Bot",[24,31,39,47,54,61,68],{"id":25,"position":18,"title":26,"body":27,"code_snippet":28,"code_language":29,"expected_result":30,"demo_url":10,"video_url":10},223,"Aggiungere le dipendenze","Assicurati di avere già configurato Firebase nel progetto tramite `flutterfire configure`. Poi aggiungi i pacchetti necessari: `firebase_core` per l'inizializzazione, `firebase_messaging` per FCM e `flutter_local_notifications` per mostrare le notifiche in foreground su Android.\n\nEsegui il comando da terminale o aggiorna manualmente il `pubspec.yaml`.","flutter pub add firebase_core firebase_messaging flutter_local_notifications","bash","I pacchetti vengono scaricati e appaiono tra le dipendenze del pubspec.yaml.",{"id":32,"position":33,"title":34,"body":35,"code_snippet":36,"code_language":37,"expected_result":38,"demo_url":10,"video_url":10},224,2,"Configurare la piattaforma Android","Per Android, verifica che nel file `android\u002Fapp\u002Fbuild.gradle` il `minSdkVersion` sia almeno **21**. Non è richiesta alcuna chiave particolare perché il file `google-services.json` generato da FlutterFire contiene già la configurazione FCM.\n\nSu iOS occorre abilitare le capability **Push Notifications** e **Background Modes > Remote notifications** in Xcode, oltre a caricare la chiave APNs nella console Firebase. In questo tutorial ci concentreremo sul flusso Dart comune alle due piattaforme.","\u002F\u002F android\u002Fapp\u002Fbuild.gradle\ndefaultConfig {\n    minSdkVersion 21\n    targetSdkVersion 34\n}","groovy","Il progetto compila correttamente su Android con le impostazioni FCM pronte.",{"id":40,"position":41,"title":42,"body":43,"code_snippet":44,"code_language":45,"expected_result":46,"demo_url":10,"video_url":10},225,3,"Inizializzare Firebase e richiedere i permessi","Nel `main()` inizializziamo Firebase prima di avviare l'app. Su iOS (e Android 13+) è necessario richiedere esplicitamente il permesso di notifica con `requestPermission()`.\n\nStampiamo lo stato di autorizzazione per verificare che l'utente abbia accettato.","import 'package:flutter\u002Fmaterial.dart';\nimport 'package:firebase_core\u002Ffirebase_core.dart';\nimport 'package:firebase_messaging\u002Ffirebase_messaging.dart';\nimport 'firebase_options.dart';\n\nFuture\u003Cvoid> main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  await Firebase.initializeApp(\n    options: DefaultFirebaseOptions.currentPlatform,\n  );\n\n  final messaging = FirebaseMessaging.instance;\n  final settings = await messaging.requestPermission(\n    alert: true,\n    badge: true,\n    sound: true,\n  );\n  debugPrint('Permesso notifiche: ${settings.authorizationStatus}');\n\n  runApp(const MyApp());\n}","dart","All'avvio l'app mostra la richiesta di permesso e nei log compare 'authorized' se l'utente accetta.",{"id":48,"position":49,"title":50,"body":51,"code_snippet":52,"code_language":45,"expected_result":53,"demo_url":10,"video_url":10},226,4,"Ottenere il token FCM del dispositivo","Ogni dispositivo ha un **token** univoco che identifica l'installazione dell'app. Questo token va inviato al tuo backend per poter indirizzare notifiche a utenti specifici.\n\nRecuperiamo il token e ascoltiamo l'evento `onTokenRefresh`, che si attiva quando il token viene rigenerato (ad esempio dopo la reinstallazione).","Future\u003Cvoid> _setupToken() async {\n  final messaging = FirebaseMessaging.instance;\n\n  final token = await messaging.getToken();\n  debugPrint('Token FCM: $token');\n  \u002F\u002F TODO: invia il token al tuo backend\n\n  messaging.onTokenRefresh.listen((newToken) {\n    debugPrint('Token aggiornato: $newToken');\n    \u002F\u002F TODO: aggiorna il token sul backend\n  });\n}","Nei log compare un token alfanumerico lungo che puoi copiare per i test dalla console Firebase.",{"id":55,"position":56,"title":57,"body":58,"code_snippet":59,"code_language":45,"expected_result":60,"demo_url":10,"video_url":10},227,5,"Gestire i messaggi in background e ad app chiusa","Quando l'app è in background o chiusa, i messaggi con solo payload dati vengono gestiti da un **handler top-level** annotato con `@pragma('vm:entry-point')`. Questa funzione deve stare fuori da qualsiasi classe.\n\nRegistriamo l'handler nel `main()` con `onBackgroundMessage`. Nota: le notifiche con payload `notification` vengono mostrate automaticamente dal sistema quando l'app non è in foreground.","@pragma('vm:entry-point')\nFuture\u003Cvoid> _firebaseBackgroundHandler(RemoteMessage message) async {\n  await Firebase.initializeApp(\n    options: DefaultFirebaseOptions.currentPlatform,\n  );\n  debugPrint('Messaggio in background: ${message.messageId}');\n  debugPrint('Dati: ${message.data}');\n}\n\n\u002F\u002F Nel main(), dopo Firebase.initializeApp:\nFirebaseMessaging.onBackgroundMessage(_firebaseBackgroundHandler);","Inviando una notifica ad app chiusa, il sistema mostra la notifica; toccandola l'app si apre e i dati sono disponibili.",{"id":62,"position":63,"title":64,"body":65,"code_snippet":66,"code_language":45,"expected_result":67,"demo_url":10,"video_url":10},228,6,"Mostrare le notifiche in foreground","In foreground FCM **non** mostra automaticamente la notifica. Usiamo `flutter_local_notifications` per visualizzarla manualmente ascoltando lo stream `onMessage`.\n\nCreiamo un canale di notifica su Android e mostriamo la notifica quando arriva un messaggio mentre l'app è aperta.","final _localNotifications = FlutterLocalNotificationsPlugin();\n\nconst _channel = AndroidNotificationChannel(\n  'high_importance_channel',\n  'Notifiche importanti',\n  importance: Importance.high,\n);\n\nFuture\u003Cvoid> _initLocalNotifications() async {\n  const initSettings = InitializationSettings(\n    android: AndroidInitializationSettings('@mipmap\u002Fic_launcher'),\n    iOS: DarwinInitializationSettings(),\n  );\n  await _localNotifications.initialize(initSettings);\n\n  await _localNotifications\n      .resolvePlatformSpecificImplementation\u003C\n          AndroidFlutterLocalNotificationsPlugin>()\n      ?.createNotificationChannel(_channel);\n\n  FirebaseMessaging.onMessage.listen((message) {\n    final notification = message.notification;\n    if (notification != null) {\n      _localNotifications.show(\n        notification.hashCode,\n        notification.title,\n        notification.body,\n        NotificationDetails(\n          android: AndroidNotificationDetails(\n            _channel.id,\n            _channel.name,\n            importance: Importance.high,\n            icon: '@mipmap\u002Fic_launcher',\n          ),\n        ),\n      );\n    }\n  });\n}","Con l'app aperta, all'arrivo di una notifica compare un banner locale con titolo e corpo del messaggio.",{"id":69,"position":70,"title":71,"body":72,"code_snippet":73,"code_language":45,"expected_result":74,"demo_url":10,"video_url":10},229,7,"Gestire il tap sulla notifica","Infine gestiamo l'apertura dell'app tramite tocco sulla notifica. Usiamo `getInitialMessage()` per il caso in cui l'app era chiusa e `onMessageOpenedApp` per quando era in background.\n\nQui puoi navigare verso una schermata specifica in base al payload ricevuto.","Future\u003Cvoid> _setupInteraction() async {\n  \u002F\u002F App aperta da stato terminato\n  final initialMessage =\n      await FirebaseMessaging.instance.getInitialMessage();\n  if (initialMessage != null) {\n    _handleMessage(initialMessage);\n  }\n\n  \u002F\u002F App aperta da background\n  FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);\n}\n\nvoid _handleMessage(RemoteMessage message) {\n  final route = message.data['route'];\n  debugPrint('Apertura tramite notifica, route: $route');\n  \u002F\u002F TODO: naviga verso la schermata indicata\n}","Toccando una notifica con un campo dati 'route', l'app registra il valore e può reindirizzare l'utente alla schermata corretta.",[],1785219609182]