fcmTemplate top-level property

String fcmTemplate
getter/setter pair

This is code to be generated.

Implementation

String fcmTemplate = """
/*
 * Created by DartGenX CLI tool on ${DateFormat('EEE, dd MMM yyyy, h:mm a').format(DateTime.now())}
 */

import 'package:${ProjectUtils.getProjectName()}/firebase_options.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

/// Background message handler (top-level)
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  debugPrint("📩 Background message: \${message.messageId}");
}

/// A service class for handling Firebase Cloud Messaging (FCM) and local notifications.
///
/// This singleton class provides methods to initialize FCM, handle notification permissions,
/// manage FCM tokens, and display local notifications. It also sets up handlers for background
/// and foreground messages, as well as notification tap events.
///
/// Usage:
/// ```dart
/// await FCMService.instance.init();
/// ```
class FCMService {
  FCMService._();

  static final FCMService instance = FCMService._();

  static final FirebaseMessaging _messaging = FirebaseMessaging.instance;
  static final FlutterLocalNotificationsPlugin _localNotifications =
      FlutterLocalNotificationsPlugin();

  String? fcmToken;

  /// Initialize Firebase Messaging
  Future<void> init() async {
    // Initialize Firebase
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );

    // Initialize local notifications
    const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher');
    const iosInit = DarwinInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
    );
    const initSettings = InitializationSettings(
      android: androidInit,
      iOS: iosInit,
    );
    await _localNotifications.initialize(
      initSettings,
      onDidReceiveNotificationResponse: (details) {
        debugPrint("🔔 Notification tapped: \${details.payload}");
      },
    );

    // Request permissions (iOS)
    final settings = await _messaging.requestPermission(
      alert: true,
      badge: true,
      sound: true,
    );
    debugPrint("🔑 FCM Permission Status: \${settings.authorizationStatus}");

    // Foreground notification presentation options (iOS)
    await _messaging.setForegroundNotificationPresentationOptions(
      alert: true,
      badge: true,
      sound: true,
    );

    // Get FCM token
    fcmToken = await _messaging.getToken();
    debugPrint("🔑 FCM Token: \$fcmToken");

    // Set background message handler
    FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);

    // Foreground messages
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      // TODO: You may need to show the notification for android manually.
      debugPrint(
        "📩 Foreground message: \${message.notification?.title} - \${message.notification?.body}",
      );
    });

    // When user taps notification
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      debugPrint("📩 Notification opened: \${message.data}");
    });

    // Handle app launched via notification
    final initialMessage = await _messaging.getInitialMessage();
    if (initialMessage != null) {
      debugPrint(
        "📩 Launched from terminated state via notification: \${initialMessage.data}",
      );
    }
  }

  /// Get current FCM token
  Future<String?> getToken() async {
    fcmToken ??= await _messaging.getToken();
    return fcmToken;
  }
}
""";