addFirebase method

List<String> addFirebase()

Implementation

List<String> addFirebase() {
  final results = <String>[];
  try {
    final file = File(_delegatePath);
    var content = file.readAsStringSync();
    var modified = false;

    // 1. Add missing imports before @UIApplicationMain / @main
    final missingImports = ['FirebaseCore', 'FirebaseMessaging', 'UserNotifications']
        .where((i) => !content.contains('import $i'))
        .toList();

    if (missingImports.isNotEmpty) {
      final marker = _annotationMarker(content);
      if (marker != null) {
        final idx = content.indexOf(marker);
        final block = missingImports.map((i) => 'import $i').join('\n') + '\n';
        content =
            content.substring(0, idx) + block + '\n' + content.substring(idx);
        modified = true;
        results.add(
            '✅ Updated AppDelegate.swift — added imports: ${missingImports.join(', ')}');
      }
    } else {
      results.add('⚠️  AppDelegate.swift — Firebase imports already exist, skipped');
    }

    // 2. Add MessagingDelegate to class signature
    if (!content.contains('MessagingDelegate')) {
      const oldSig = 'FlutterAppDelegate {';
      const newSig = 'FlutterAppDelegate, MessagingDelegate {';
      if (content.contains(oldSig)) {
        content = content.replaceFirst(oldSig, newSig);
        modified = true;
        results.add('✅ Updated AppDelegate.swift — added MessagingDelegate');
      }
    } else {
      results.add(
          '⚠️  AppDelegate.swift — MessagingDelegate already exists, skipped');
    }

    // 3. Add Firebase setup inside didFinishLaunching (before GeneratedPluginRegistrant).
    //    Anchor includes the 4-space indent so replaceFirst consumes those spaces
    //    and the setup lines start at the same 4-space indent — avoiding the
    //    8-space bug that results from the original indent being left in place.
    const registrant = '    GeneratedPluginRegistrant.register(with: self)';
    if (!content.contains('FirebaseApp.configure()')) {
      if (content.contains(registrant)) {
        const setup = '    FirebaseApp.configure()\n'
            '    UNUserNotificationCenter.current().delegate = self\n'
            '    Messaging.messaging().delegate = self\n'
            '    UNUserNotificationCenter.current().requestAuthorization(\n'
            '      options: [.alert, .sound, .badge]\n'
            '    ) { _, _ in }\n'
            '    application.registerForRemoteNotifications()\n';
        content = content.replaceFirst(registrant, '$setup$registrant');
        modified = true;
        results.add('✅ Updated AppDelegate.swift — added Firebase setup');
      }
    } else {
      results.add(
          '⚠️  AppDelegate.swift — FirebaseApp.configure() already exists, skipped');
    }

    // 4. Add Firebase delegate methods after didFinishLaunching
    final methodsToAdd = <String>[];
    if (!content.contains('didRegisterForRemoteNotificationsWithDeviceToken')) {
      methodsToAdd.add(_deviceTokenMethod);
    }
    if (!content
        .contains('func messaging(_ messaging: Messaging, didReceiveRegistrationToken')) {
      methodsToAdd.add(_messagingTokenMethod);
    }
    if (!content.contains('func userNotificationCenter')) {
      methodsToAdd.add(_notificationCenterMethod);
    }

    if (methodsToAdd.isNotEmpty) {
      final block = '\n\n' + methodsToAdd.join('\n\n') + '\n';
      content = _insertAfterDidFinishLaunching(content, block);
      modified = true;
      results.add(
          '✅ Updated AppDelegate.swift — added Firebase delegate methods');
    } else {
      results.add(
          '⚠️  AppDelegate.swift — Firebase methods already exist, skipped');
    }

    if (modified) file.writeAsStringSync(content);
  } catch (e) {
    results.add('❌ Failed to update AppDelegate.swift: $e');
  }
  return results;
}