ensureFirestoreDatabase method
Ensure the default Firestore database exists for projectId.
Runs gcloud firestore databases describe --database=(default) to
detect existence; on NOT_FOUND runs gcloud firestore databases create --location=REGION --type=firestore-native.
Defaults to multi-region region nam5 (US). Other common values:
• eur3 — multi-region EU
• us-central1, europe-west1, asia-northeast1 — regional
Any failure other than NOT_FOUND is surfaced via FirestoreInitResult.message without throwing, so callers can downgrade to a console hand-off.
Implementation
Future<FirestoreInitResult> ensureFirestoreDatabase({
String region = 'nam5',
}) async {
if (projectId.isEmpty) {
return FirestoreInitResult(
existed: false,
created: false,
region: region,
message: 'No Firebase project ID configured',
);
}
info('Checking Firestore default database for $projectId...');
final ProcessResult describe = await _runner.run('gcloud', <String>[
'firestore',
'databases',
'describe',
'--database=(default)',
'--project=$projectId',
'--format=json',
]);
if (describe.success) {
final String? existingRegion = _extractFirestoreRegion(describe.stdout);
info('Firestore database already exists '
'${existingRegion != null ? '(region: $existingRegion)' : ''}');
return FirestoreInitResult(
existed: true,
created: false,
region: existingRegion ?? region,
);
}
final String stderr = describe.stderr;
// Special-case: API not enabled. We surface a clear hand-off so the
// wizard can offer "auto-enable + retry".
if (_isApiNotEnabledError(stderr, 'firestore.googleapis.com')) {
return FirestoreInitResult(
existed: false,
created: false,
region: region,
message:
'Cloud Firestore API is not enabled for $projectId. Enable it via:\n'
' • gcloud services enable firestore.googleapis.com --project=$projectId\n'
' • or open: ${apiEnableUrl(projectId, 'firestore.googleapis.com')}',
);
}
if (FirebaseBillingService.isBillingAbsentError(stderr)) {
return FirestoreInitResult(
existed: false,
created: false,
region: region,
message:
'Billing is not enabled on $projectId. Upgrade to Blaze first:\n'
' ${FirebaseBillingService.upgradeUrl(projectId)}',
);
}
if (!_isNotFoundError(stderr)) {
// Don't block on permission / auth issues — caller can hand off.
return FirestoreInitResult(
existed: false,
created: false,
region: region,
message: stderr.trim().isEmpty
? 'gcloud firestore describe exited ${describe.exitCode}'
: stderr.trim(),
);
}
info('Creating Firestore default database in $region...');
final ProcessResult create = await _runner.run('gcloud', <String>[
'firestore',
'databases',
'create',
'--database=(default)',
'--location=$region',
'--project=$projectId',
'--type=firestore-native',
]);
if (create.success) {
success('Firestore database created (region: $region).');
return FirestoreInitResult(
existed: false,
created: true,
region: region,
message: 'Created in $region',
);
}
final String createErr = create.stderr;
if (FirebaseBillingService.isBillingAbsentError(createErr)) {
return FirestoreInitResult(
existed: false,
created: false,
region: region,
message:
'Billing is not enabled on $projectId. Upgrade to Blaze first:\n'
' ${FirebaseBillingService.upgradeUrl(projectId)}',
);
}
return FirestoreInitResult(
existed: false,
created: false,
region: region,
message: createErr.trim().isEmpty
? 'gcloud firestore create exited ${create.exitCode}'
: createErr.trim(),
);
}