Firebase Provider (drft_firebase)
The Firebase provider enables DRFT to manage Firebase projects and apps - essential infrastructure for Flutter applications.
Why Firebase Provider?
- Flutter Ecosystem: Most Flutter apps use Firebase for backend services
- Comprehensive Configuration: Projects and apps for iOS, Android, and Web
- Terraform Gap: Limited Firebase support in Terraform
- High Value: Solves real pain points for Flutter developers
Configuration
The Firebase provider uses the firebase_management package and supports Application Default Credentials (ADC) or explicit credential configuration.
import 'package:drft/drft.dart';
import 'package:drft_firebase/drft_firebase.dart';
import 'package:firebase_management/firebase_management.dart';
final provider = FirebaseProvider(
// Optional: provide credentials explicitly
// If not provided, will use Application Default Credentials
credentials: Credentials.fromServiceAccount('path/to/service-account.json'),
);
Authentication
The provider supports multiple authentication methods:
-
Application Default Credentials (ADC) - Recommended for local development
gcloud auth application-default login -
Service Account JSON - For production and CI/CD
FirebaseProvider( credentials: Credentials.fromServiceAccount('service-account.json'), ) -
Environment Variables - Set
GOOGLE_APPLICATION_CREDENTIALSexport GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
Firebase Project
Represents a Firebase project that exists externally. This is a data source - it cannot be created, updated, or deleted through DRFT. Projects must be managed through the Firebase Console or Google Cloud Console.
FirebaseProject(
id: 'my-project',
projectId: 'my-project-id', // Must match existing Firebase project
displayName: 'My Firebase Project',
)
Properties:
id(required): Unique identifier for the resource in DRFTprojectId(required): The Firebase project ID (must be globally unique)displayName(required): Display name for the project
Operations:
- ✅ Read: Verify project exists and get current state
- ❌ Create: Not supported (create via Firebase Console)
- ❌ Update: Not supported (data source - read-only)
- ❌ Delete: Not supported (delete via Firebase Console)
Data Source Behavior:
FirebaseProjectextendsReadOnlyResource(read-only external resource)- It will never appear in create, update, or delete operations
- It is read during planning and refresh to verify existence
- Other resources (like
FirebaseApp) can depend on it to get theprojectId
Firebase App
Represents a Firebase app (iOS, Android, or Web) within a Firebase project. Supports full CRUD operations.
// iOS App
FirebaseApp(
id: 'ios-app',
projectId: 'my-project-id',
platform: FirebaseAppPlatform.ios,
displayName: 'My iOS App',
bundleId: 'com.example.app', // Required for iOS
)
// Android App
FirebaseApp(
id: 'android-app',
projectId: 'my-project-id',
platform: FirebaseAppPlatform.android,
displayName: 'My Android App',
packageName: 'com.example.app', // Required for Android
)
// Web App
FirebaseApp(
id: 'web-app',
projectId: 'my-project-id',
platform: FirebaseAppPlatform.web,
displayName: 'My Web App',
)
Properties:
id(required): Unique identifier for the resource in DRFTprojectId(required): The Firebase project ID this app belongs toplatform(required):FirebaseAppPlatform.ios,.android, or.webdisplayName(required): Display name of the appbundleId(optional): Bundle ID for iOS apps (required when platform is iOS)packageName(optional): Package name for Android apps (required when platform is Android)
Operations:
- ✅ Create: Creates new Firebase app for the specified platform
- ✅ Read: Reads current app state from Firebase
- ✅ Update: Updates app display name (other properties are immutable)
- ⚠️ Delete: Placeholder (API support pending)
Immutable Properties: Once created, the following properties cannot be changed:
platform- Cannot change app platformbundleId- Cannot change iOS bundle IDpackageName- Cannot change Android package name
Updatable Properties:
displayName- Can be updated using theupdateAppmethod
Coming Soon
The following resources are planned for future releases:
- Firebase Authentication - Configure authentication providers and settings
- Firestore Database - Create and manage Firestore databases
- Cloud Storage - Manage Cloud Storage buckets
- Remote Config - Configure remote configuration parameters
- App Check - Set up App Check providers
Complete Example
import 'package:drft/drft.dart';
import 'package:drft_firebase/drft_firebase.dart';
void main() async {
final stack = DrftStack(
name: 'flutter-app-backend',
providers: [
FirebaseProvider(
// Uses Application Default Credentials if not provided
// credentials: Credentials.fromServiceAccount('service-account.json'),
),
],
resources: [
// Firebase Project (must exist in Firebase Console)
FirebaseProject(
id: 'my-project',
projectId: 'my-flutter-app',
displayName: 'My Flutter App Backend',
),
// iOS App
FirebaseApp(
id: 'ios-app',
projectId: 'my-flutter-app',
platform: FirebaseAppPlatform.ios,
displayName: 'My iOS App',
bundleId: 'com.example.app',
),
// Android App
FirebaseApp(
id: 'android-app',
projectId: 'my-flutter-app',
platform: FirebaseAppPlatform.android,
displayName: 'My Android App',
packageName: 'com.example.app',
),
// Web App
FirebaseApp(
id: 'web-app',
projectId: 'my-flutter-app',
platform: FirebaseAppPlatform.web,
displayName: 'My Web App',
),
],
);
// Plan changes
final plan = await stack.plan();
print(plan.summary);
// Apply changes
final result = await stack.apply(plan);
print(result.summary);
}
Creating Firebase Apps
final stack = DrftStack(
name: 'my-stack',
providers: [FirebaseProvider()],
resources: [
FirebaseProject(
id: 'project',
projectId: 'my-project-id',
displayName: 'My Project',
),
FirebaseApp(
id: 'ios-app',
projectId: 'my-project-id',
platform: FirebaseAppPlatform.ios,
displayName: 'iOS App',
bundleId: 'com.example.app',
),
],
);
// Plan and apply
final plan = await stack.plan();
await stack.apply(plan);
Updating App Display Name
// After initial creation, you can update the display name
final updatedApp = FirebaseApp(
id: 'ios-app',
projectId: 'my-project-id',
platform: FirebaseAppPlatform.ios,
displayName: 'Updated App Name', // Changed display name
bundleId: 'com.example.app',
);
final plan = await stack.plan();
await stack.apply(plan);
Reading Current State
// Refresh state from actual Firebase infrastructure
final currentState = await stack.refresh();
// Access app state
final appState = currentState.resources['ios-app'] as FirebaseAppState;
print('App ID: ${appState.appId}');
print('Display Name: ${appState.resource.displayName}');
Authentication
The Firebase provider uses the firebase_management package and supports:
- Application Default Credentials (ADC) - Recommended for local development
- Service Account JSON - For production and CI/CD
- Environment Variables - Via
GOOGLE_APPLICATION_CREDENTIALS
API Limitations
- Project Creation/Deletion: Must be done through Firebase Console or Google Cloud Console
- App Deletion: Currently not supported by the API (placeholder implementation)
- Immutable Properties: Platform, bundleId, and packageName cannot be changed after creation
- Rate Limits: Firebase Management API has rate limits that may affect operations
State Management
Firebase resources are tracked by their resource IDs in DRFT:
- Projects: Tracked by
projectId - Apps: Tracked by
idwith matching logic based on platform and bundleId/packageName/displayName
The provider automatically retrieves the Firebase-assigned appId after creation, which is stored in FirebaseAppState.
Resource Matching
When reading Firebase apps, the provider matches apps using:
- Platform match (iOS, Android, or Web)
- Bundle ID match (for iOS) or Package Name match (for Android)
- Display Name match (fallback)
Phase 1 (Current) ✅
- ✅ Firebase Projects (read support)
- ✅ Firebase Apps (iOS, Android, Web) - full CRUD operations
- ✅ Create apps
- ✅ Read apps
- ✅ Update display name
- ⚠️ Delete apps (API support pending)