injectFirebase static method
Injects Firebase initialization code into the entry point files.
If separate is true, it injects into lib/main/main_<flavor>.dart.
Otherwise, it injects into lib/main.dart.
Implementation
static void injectFirebase({required bool separate, String? flavor}) {
final root = ConfigService.root;
final config = ConfigService.load();
final strategy = config.firebase?.strategy;
final flavors = config.flavors;
if (separate) {
if (flavor == null) {
for (final f in flavors) {
injectFirebase(separate: true, flavor: f);
}
return;
}
final mainPath = p.join(root, 'lib/main/main_$flavor.dart');
final file = File(mainPath);
if (!file.existsSync()) return;
final optionsFile = strategy == 'shared_id_single_project'
? 'firebase_options.dart'
: 'firebase_options_$flavor.dart';
final configFile = File(p.join(root, 'lib/$optionsFile'));
if (!configFile.existsSync()) return;
var content = file.readAsStringSync();
// 1. Manage Imports
if (!content.contains('firebase_core.dart')) {
content = "import 'package:firebase_core/firebase_core.dart';\n"
"import '../$optionsFile';\n$content";
} else if (!content.contains(optionsFile)) {
content = "import '../$optionsFile';\n$content";
}
// 2. Inject Initialization
if (content.contains('Firebase.initializeApp')) {
return; // Skip if already initialized
}
final initRegex = RegExp(
r'^(\s*)AppConfig\.init\s*\(.*\);',
multiLine: true,
);
final match = initRegex.firstMatch(content);
if (match != null) {
final indent = match.group(1) ?? ' ';
final ensureInitialized =
content.contains('WidgetsFlutterBinding.ensureInitialized()')
? ""
: "${indent}WidgetsFlutterBinding.ensureInitialized();\n";
final initBlock =
"\n$ensureInitialized${indent}await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);";
final mainRegex = RegExp(r'void main\s*\(\s*\)\s*(async\s*)?{');
content = content.replaceFirst(mainRegex, 'void main() async {');
content = content.replaceFirst(
match.group(0)!,
'${match.group(0)!}$initBlock',
);
file.writeAsStringSync(content);
}
} else {
// Single Main Strategy
final mainPath = p.join(root, 'lib/main.dart');
final file = File(mainPath);
if (!file.existsSync()) return;
var content = file.readAsStringSync();
if (strategy == 'shared_id_single_project') {
final configFile = File(p.join(root, 'lib/firebase_options.dart'));
if (!configFile.existsSync()) return;
if (!content.contains('firebase_core.dart')) {
content = "import 'package:firebase_core/firebase_core.dart';\n"
"import 'firebase_options.dart';\n$content";
}
if (!content.contains('Firebase.initializeApp')) {
final initRegex = RegExp(
r'^(\s*)AppConfig\.init\s*\(.*\);',
multiLine: true,
);
final match = initRegex.firstMatch(content);
if (match != null) {
final indent = match.group(1) ?? ' ';
final ensureInitialized =
content.contains('WidgetsFlutterBinding.ensureInitialized()')
? ""
: "${indent}WidgetsFlutterBinding.ensureInitialized();\n";
final initBlock =
"\n$ensureInitialized${indent}await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);";
final mainRegex = RegExp(r'void main\s*\(\s*\)\s*(async\s*)?{');
content = content.replaceFirst(mainRegex, 'void main() async {');
content = content.replaceFirst(
match.group(0)!,
'${match.group(0)!}$initBlock',
);
}
}
} else {
// Multi-Options Injection (Unique ID strategies)
final configuredFlavors = flavors.where((f) {
return File(
p.join(root, 'lib/firebase_options_$f.dart'),
).existsSync();
}).toList();
if (configuredFlavors.isEmpty) return;
// Clean existing to regenerate
content = content.replaceAll(
RegExp(
r'''import ['"]package:firebase_core/firebase_core\.dart['"];\n?''',
),
'',
);
content = content.replaceAll(
RegExp(r'''import ['"]firebase_options_.*\.dart['"] as \w+;\n?'''),
'',
);
final importBuffer = StringBuffer();
importBuffer.writeln(
"import 'package:firebase_core/firebase_core.dart';",
);
for (final f in configuredFlavors) {
importBuffer.writeln("import 'firebase_options_$f.dart' as $f;");
}
content = importBuffer.toString() + content.trimLeft();
final initRegex = RegExp(
r'await Firebase\.initializeApp\s*\([\s\S]*?\);',
);
String indent = ' ';
final configInitRegex = RegExp(
r'^(\s*)AppConfig\.init\s*\(.*\);',
multiLine: true,
);
final configMatch = configInitRegex.firstMatch(content);
if (configMatch != null) indent = configMatch.group(1) ?? ' ';
final buffer = StringBuffer();
buffer.writeln("await Firebase.initializeApp(");
buffer.writeln("$indent options: switch (flavor) {");
for (final f in configuredFlavors) {
buffer.writeln(
"$indent Flavor.$f => $f.DefaultFirebaseOptions.currentPlatform,",
);
}
if (configuredFlavors.length < flavors.length) {
buffer.writeln(
"$indent _ => ${configuredFlavors.first}.DefaultFirebaseOptions.currentPlatform,",
);
}
buffer.writeln("$indent },");
buffer.write("$indent)");
if (content.contains('Firebase.initializeApp')) {
content = content.replaceFirst(
initRegex,
buffer.toString().trim() + ';',
);
} else if (configMatch != null) {
final indent = configMatch.group(1) ?? ' ';
final ensureInitialized =
content.contains('WidgetsFlutterBinding.ensureInitialized()')
? ""
: "${indent}WidgetsFlutterBinding.ensureInitialized();\n";
final initBlock =
"\n$ensureInitialized${indent}${buffer.toString().trim()};";
final mainRegex = RegExp(r'void main\s*\(\s*\)\s*(async\s*)?{');
content = content.replaceFirst(mainRegex, 'void main() async {');
content = content.replaceFirst(
configMatch.group(0)!,
'${configMatch.group(0)!}$initBlock',
);
}
}
file.writeAsStringSync(content);
}
}