run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<int> run() async {
final filePath = argResults!['file'] as String;
final merge = argResults!['merge'] as bool;
final apply = argResults!['apply'] as bool;
final verbose = argResults!['verbose'] as bool;
final result = OperationResult();
try {
stdout.writeln('Loading JSON from $filePath...');
final json = await JsonValidator.loadJsonFile(filePath);
final collectionMap = JsonValidator.validateObject(json, 'Root JSON');
final importPlan = _validateImportStructure(collectionMap);
stdout
..writeln('\n=== Import Plan ===')
..writeln('Collections: ${importPlan.length}')
..writeln('Mode: ${merge ? 'Merge' : 'Replace'}');
var totalDocs = 0;
for (final collection in importPlan) {
stdout.writeln(
' ${collection.path}: ${collection.documents.length} documents'
'${collection.idFieldName != null ? ' (ID field: ${collection.idFieldName})' : ''}',
);
totalDocs += collection.documents.length;
}
stdout.writeln('Total documents: $totalDocs');
if (!apply) {
stdout
..writeln('\n⚠️ DRY RUN MODE - No changes will be made')
..writeln('Use --apply to execute the operation');
return 0;
}
stdout.writeln('\nConnecting to Firestore...');
final client = await FirestoreClient.fromEnvironment();
stdout.writeln(
'Importing $totalDocs documents across ${importPlan.length} collections...',
);
for (final collection in importPlan) {
stdout.writeln('\nCollection: ${collection.path}');
for (var i = 0; i < collection.documents.length; i++) {
final doc = collection.documents[i];
String? docId;
if (collection.idFieldName != null &&
doc.containsKey(collection.idFieldName)) {
docId = doc[collection.idFieldName]?.toString();
}
await _writeDocument(
client: client,
collectionPath: collection.firestorePath,
documentId: docId,
data: doc,
merge: merge,
result: result,
index: i,
);
if ((i + 1) % 10 == 0 || i == collection.documents.length - 1) {
stdout.write(
'\r Progress: ${i + 1}/${collection.documents.length}',
);
}
}
stdout.writeln();
}
result.printSummary(verbose: verbose);
return result.hasErrors ? 1 : 0;
} on Exception catch (e) {
stderr.writeln('Error: $e');
return 2;
}
}