When initializing Firebase, you may see:
FirebaseApp with name [DEFAULT] already exists
Flutter may report:
[core/duplicate-app]
A Firebase App named "[DEFAULT]" already exists
The app is attempting to create another FirebaseApp with a name that is already registered.
In most cases this is not a Firebase bug: a startup path is creating the default app more than once, or — after a Firebase project change — configuration files disagree about which Firebase project [DEFAULT] should use.
Quick fix
This error usually means one of two things:
- the default Firebase app is being initialized more than once, or
- after a Firebase project/configuration change, two configuration paths are trying to create
[DEFAULT]with different options.
Work through these checks in order:
- Search the project for every
Firebase.initializeApp/FirebaseApp.initializeAppcall - On standard native Android, check whether
FirebaseInitProvideralready initializes[DEFAULT](see Android cause 1 below) - In Flutter, make sure
Firebase.initializeAppruns in one startup path only - If the error started after switching Firebase projects or running
flutterfire configure, verify thatfirebase_options.dartand the native Firebase configuration files (google-services.json,GoogleService-Info.plist) still point to the same intended Firebase app/project - Use a named Firebase app only when the application intentionally connects to an additional Firebase project
Do not add a name only to silence [core/duplicate-app].
A named FirebaseApp is appropriate when you intentionally use an additional Firebase project. If the app is supposed to have only one default Firebase project, first find why [DEFAULT] is being created twice or with conflicting configuration.
To go straight to the likely cause, match the symptom:
| Symptom | First suspect |
|---|---|
| Native Android, right at startup | Automatic and manual default initialization both enabled |
| Flutter, fired from more than one service or bootstrap | A duplicate Dart initialization path |
| Right after switching Firebase projects | Generated/native configuration mismatch |
| Only one build flavor fails | Stale flavor-specific Firebase config |
| Two Firebase projects used at the same time on purpose | The secondary app needs a unique name |
| Only after Hot Restart | A lifecycle / repeated initialization path |
These are starting points, not verdicts — each suspect has its own section below.
Initialization versus retrieval
Create a FirebaseApp
Android:
FirebaseApp.initializeApp(context, options)
Flutter:
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
Retrieve an existing FirebaseApp
Android:
FirebaseApp.getInstance()
Flutter:
final app = Firebase.app();
When you only need the existing default app, retrieve it instead of initializing it again.
Android cause 1: Automatic and manual initialization are both enabled
In a standard Android app, FirebaseInitProvider initializes [DEFAULT] automatically.
Manually initializing it again from Application can create a duplicate:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
FirebaseApp.initializeApp(this, options)
}
}
For a standard setup, remove the manual initialization and retrieve the existing app:
val app = FirebaseApp.getInstance()
Android cause 2: Initialization exists in multiple places
Search the whole project for:
FirebaseApp.initializeApp
FirebaseOptions.Builder
[DEFAULT]
Check locations such as:
- Application
- Activity
- Service
- ContentProvider
- Dependency-injection modules
- Startup managers
- Flavor-specific source sets
Assign responsibility for creating each FirebaseApp to one startup path.
Flutter cause 1: Firebase is initialized outside main as well
Example:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
await FirebaseService.initialize();
runApp(const MyApp());
}
If FirebaseService.initialize() performs the same Firebase.initializeApp() call, the second call can fail.
Service classes should use existing instances:
class FirebaseService {
FirebaseApp get app => Firebase.app();
FirebaseAuth get auth => FirebaseAuth.instance;
}
Flutter cause 2: Initialization is inside a Widget build method
build() can run many times.
Avoid:
Widget build(BuildContext context) {
Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
return const HomePage();
}
Place initialization in main() or another startup function that runs once.
Flutter cause 3: A Provider is recreated
Initialization inside a Provider or Riverpod factory may run again when its lifecycle recreates the provider.
Initialize during startup and pass the created app into the provider layer:
final app = await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(
ProviderScope(
overrides: [firebaseAppProvider.overrideWithValue(app)],
child: const MyApp(),
),
);
Flutter cause 4: Configuration files disagree after switching Firebase projects
Check this first if the error appeared after:
- switching from one Firebase project to another
- deleting and recreating a Firebase app
- rerunning
flutterfire configure - adding flavors or separate development/production Firebase projects
- copying a project that already contained Firebase configuration
This is a different failure from a duplicated initializeApp call: the app intends to use one Firebase project, but stale, native, or generated configuration files disagree about which one, so [DEFAULT] ends up created with conflicting options.
A Flutter project can hold several Firebase configuration sources at the same time:
lib/firebase_options.dartandroid/app/google-services.json- Android flavor-specific
google-services.jsonfiles ios/Runner/GoogleService-Info.plist- any flavor/environment-specific Apple configuration files
Do not assume fixed paths. Search the whole project for files with these names — after a project switch or a flavor rename it is common to find more than one copy, and only some of them are stale.
Compare what each location says:
| Location | What to compare |
|---|---|
firebase_options.dart | projectId, platform appId, intended environment |
google-services.json | project ID, Android Firebase app ID, package name |
GoogleService-Info.plist | project ID, Google app ID, bundle ID |
| flavor-specific configs | Whether the active flavor points to the intended Firebase project |
The values are not expected to be identical strings — each format describes the Firebase app in its own shape. They should describe the Firebase app/project that the currently built variant is intended to use. Firebase config files and firebase_options.dart exist precisely to associate an app with one Firebase project (see Understand Firebase projects), so disagreement between them means the build no longer has a single intended project.
How to realign the configuration
- Decide which Firebase project the current build should use
- Check
firebase_options.dartfor that platform - Search for native Firebase config files that belong to an old project or flavor
- Re-run
flutterfire configurefor the intended Firebase project/platforms - Re-check the generated configuration
- Remove only configuration files that are confirmed stale and no longer used
- Run
flutter clean - Rebuild the app
flutterfire configure generates/updates firebase_options.dart for the Firebase project and platforms you select for the Flutter app. After changing Firebase projects or platform configuration, rerun it and verify that the generated Flutter options and the native project files describe the environment you intend to build. Rerunning it is one step of realigning the configuration, not a guaranteed fix on its own — a stale native config file can still disagree with the generated options.
Do not delete configuration files blindly. A native config file may still be required by the active platform, flavor, Crashlytics, or another Firebase integration. First identify which file is stale and which build variant uses it.
For what each field in google-services.json means and where the file belongs, see What Is google-services.json? Placement, Updates, and Project Checks. When development, staging, and production each use their own Firebase project, the flavor setup decides which configuration a built variant receives — see How to Separate Firebase Development and Production Environments.
Cause 5: Multiple main files and a shared bootstrap both initialize
A project may contain:
main_development.dart
main_production.dart
bootstrap.dart
Check whether each main file initializes Firebase before calling a shared bootstrap that initializes it again.
A clearer design gives the bootstrap function sole responsibility:
Future<void> bootstrap(FirebaseOptions options) async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: options);
runApp(const MyApp());
}
Cause 6: Two Firebase projects use the same app name
This is the intentional multi-project case: the application is designed to connect to more than one Firebase project at runtime. It is a different problem from Flutter cause 4 — there, one project is intended and the configuration files disagree about which one, so the configuration itself must be realigned.
Both calls below use the default name because neither specifies name:
await Firebase.initializeApp(
options: primaryOptions,
);
await Firebase.initializeApp(
options: secondaryOptions,
);
Only create a named secondary FirebaseApp when the application genuinely needs simultaneous access to another Firebase project.
Give the second app a unique name:
final secondary = await Firebase.initializeApp(
name: 'secondary',
options: secondaryOptions,
);
Then obtain services from that named app:
final auth = FirebaseAuth.instanceFor(app: secondary);
A named app is useful only when the application intentionally connects to more than one Firebase project. Do not create extra apps merely to hide a duplicate default initialization. Do not create a second named app merely because the default configuration files disagree — realign the configuration first (Flutter cause 4).
Cause 7: Old manual Flutter Web initialization remains
Check whether web/index.html still initializes Firebase in JavaScript in addition to Dart:
<script>
firebase.initializeApp(firebaseConfig);
</script>
With a current FlutterFire setup, Firebase initialization should normally be owned by the Dart startup path.
When it happens only after Hot Restart
Hot Restart reruns Dart startup code. A Full Restart may temporarily clear the state, but multiple initialization paths can make the error return.
flutter clean behaves the same way: removing build artifacts can make the error disappear for one run, but it is not a permanent fix if multiple initialization paths or a configuration mismatch remain. If a clean or a restart only postpones the error, confirm that one startup path owns initialization and that the configuration files agree on the Firebase project.
Check all of the following:
- Search every
initializeAppcall - Review native Android initialization
- Review manual JavaScript initialization on web
- Confirm that different options are not assigned to the same app name
A restart is not a permanent fix for duplicate ownership of initialization.
When it happens in tests
Tests may create the same named app repeatedly.
Use a dedicated name and delete it after the test suite:
late FirebaseApp testApp;
setUpAll(() async {
testApp = await Firebase.initializeApp(
name: 'test-app',
options: testOptions,
);
});
tearDownAll(() async {
await testApp.delete();
});
Avoid using the production [DEFAULT] app as disposable test state.
Inspect registered apps
Android:
FirebaseApp.getApps(context).forEach {
Log.d("Firebase", "${it.name}: ${it.options.projectId}")
}
Flutter:
for (final app in Firebase.apps) {
debugPrint('${app.name}: ${app.options.projectId}');
}
After confirming that an app with the required name exists, replace creation calls with retrieval where appropriate.
Do not catch and ignore the error
Avoid:
try {
await Firebase.initializeApp();
} catch (_) {}
This also hides unrelated configuration and network errors. Identify the duplicate initialization path instead.
Summary
The basic fix for duplicate-app is:
- Search every
initializeAppcall - Do not combine Android automatic and manual default initialization
- Initialize once in Flutter
main()or a single bootstrap function - Do not initialize from rebuildable Widgets or Providers
- Give additional FirebaseApp instances unique names
- Retrieve existing apps with
getInstance()orFirebase.app() - After switching Firebase projects, verify that
firebase_options.dartand the native configuration files describe the project the build intends to use
When [DEFAULT] does not exist instead, see Fix Default FirebaseApp Is Not Initialized.
Primary sources
Official references
- FirebaseApp Android API reference
- Firebase: Add Firebase to your Flutter app
- Understand Firebase projects
Check the linked official documentation before a production release.
Continue reading
Related guides
TestCrew
Find testers through mutual testing
Test other Android apps, provide useful feedback, and use earned credits to recruit testers for your own Google Play closed test.
Learn how TestCrew works