TestCrew
Firebase and Android Setup

Fix FirebaseApp with Name [DEFAULT] Already Exists

Fix FirebaseApp [DEFAULT] already exists and core/duplicate-app errors by removing duplicate initialization in Android, Flutter, providers, hot restart, tests, and multi-project setups.

Published
August 2, 2026
Updated
September 26, 2026
Official info checked
September 26, 2026
TestCrew guide cover for fixing FirebaseApp default already exists

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:

  1. the default Firebase app is being initialized more than once, or
  2. after a Firebase project/configuration change, two configuration paths are trying to create [DEFAULT] with different options.

Work through these checks in order:

  1. Search the project for every Firebase.initializeApp / FirebaseApp.initializeApp call
  2. On standard native Android, check whether FirebaseInitProvider already initializes [DEFAULT] (see Android cause 1 below)
  3. In Flutter, make sure Firebase.initializeApp runs in one startup path only
  4. If the error started after switching Firebase projects or running flutterfire configure, verify that firebase_options.dart and the native Firebase configuration files (google-services.json, GoogleService-Info.plist) still point to the same intended Firebase app/project
  5. 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:

SymptomFirst suspect
Native Android, right at startupAutomatic and manual default initialization both enabled
Flutter, fired from more than one service or bootstrapA duplicate Dart initialization path
Right after switching Firebase projectsGenerated/native configuration mismatch
Only one build flavor failsStale flavor-specific Firebase config
Two Firebase projects used at the same time on purposeThe secondary app needs a unique name
Only after Hot RestartA 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.dart
  • android/app/google-services.json
  • Android flavor-specific google-services.json files
  • 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:

LocationWhat to compare
firebase_options.dartprojectId, platform appId, intended environment
google-services.jsonproject ID, Android Firebase app ID, package name
GoogleService-Info.plistproject ID, Google app ID, bundle ID
flavor-specific configsWhether 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

  1. Decide which Firebase project the current build should use
  2. Check firebase_options.dart for that platform
  3. Search for native Firebase config files that belong to an old project or flavor
  4. Re-run flutterfire configure for the intended Firebase project/platforms
  5. Re-check the generated configuration
  6. Remove only configuration files that are confirmed stale and no longer used
  7. Run flutter clean
  8. 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 initializeApp call
  • 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:

  1. Search every initializeApp call
  2. Do not combine Android automatic and manual default initialization
  3. Initialize once in Flutter main() or a single bootstrap function
  4. Do not initialize from rebuildable Widgets or Providers
  5. Give additional FirebaseApp instances unique names
  6. Retrieve existing apps with getInstance() or Firebase.app()
  7. After switching Firebase projects, verify that firebase_options.dart and 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

Check the linked official documentation before a production release.

Continue reading

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

Analytics settings

TestCrew uses Google Analytics provided by Google LLC to improve the website. You can change whether it is used; this applies to future measurement on this page and later visits. See the Privacy Policy.