angularfire icon indicating copy to clipboard operation
angularfire copied to clipboard

how to Initialize the config dynamically?

Open imalitavakoli opened this issue 1 year ago • 2 comments

I'm looking for a simple way to initializeApp later inside of the app.component.ts NOT in my app.config.ts. I need to do this because of my current app implementation and requirements...

Currently, here's my app.config.ts file:

import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
import { getAnalytics, provideAnalytics } from '@angular/fire/analytics';

export const appConfig: ApplicationConfig = {
  providers: [
    provideFirebaseApp(() =>
      initializeApp({
        apiKey: 'xxx',
        authDomain: 'xxx.firebaseapp.com',
        databaseURL: 'https://xxx.firebaseio.com',
        projectId: 'xxx',
        storageBucket: 'xxx',
        messagingSenderId: '123',
        appId: 'xxx',
        measurementId: 'xxx',
      }),
    ),
    provideAnalytics(() => getAnalytics()),
    ...
  ],
  ...
})

Any help is so appreciated ❤️

Version info

Angular: 17.3.3

Firebase: ^10.13.1

AngularFire: ^18.0.1

imalitavakoli avatar Sep 01 '24 08:09 imalitavakoli

This issue does not seem to follow the issue template. Make sure you provide all the required information.

google-oss-bot avatar Sep 01 '24 08:09 google-oss-bot

Hi @imalitavakoli, below is one way I solved this problem:

  1. Initialize the default Firebase app in your module configuration.

In your app.module.ts (or equivalent configuration file), import Firebase with the default configuration. This makes Firebase available to your entire app without immediately loading all specific services.

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AngularFireModule } from '@angular/fire/compat';
import { environment } from '../environments/environment';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    // Default initialization using your base firebaseConfig:
    AngularFireModule.initializeApp(environment.firebaseConfig),
    // ... other imports
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

  1. Reinitialize or further configure Firebase in your component.

Later—in your app.component.ts—you can import Firebase’s core functions and initialize (or get) the app again. Then, if you need to set up additional services (for example, a custom database configuration or other specifics), you can do so here. One common pattern is to check whether the app is already initialized, then either use it or initialize a new (possibly named) instance if needed. For example:

// app.component.ts
import { Component, OnInit } from '@angular/core';
import { initializeApp, getApps, getApp } from 'firebase/app';
import { getDatabase } from 'firebase/database';
import { environment } from '../environments/environment';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  ngOnInit() {
    let appInstance;
    
    // Use the default initialized app if it exists,
    // otherwise initialize it here.
    if (getApps().length) {
      appInstance = getApp();
    } else {
      appInstance = initializeApp(environment.firebaseConfig);
    }

    // Now, for instance, get the database using the (possibly reinitialized) app.
    const database = getDatabase(appInstance);
    
    // Continue with any further initialization or service configuration here.
    // For example, you could conditionally configure other services based on your app's state.
  }
}

Explanation in a Nutshell: • Default Import: I import and initialize Firebase by default in app.module.ts so that the basic Firebase setup is available immediately throughout the app. • Deferred/Specific Initialization: Later in app.component.ts, I “reinitialize” (or simply retrieve) the Firebase app. This lets me add specific configurations—like initializing the database with a particular setup—based on my app’s runtime requirements. • Avoiding Duplicate Initialization: By checking getApps().length, I ensure that I don’t accidentally initialize the default app twice. If you need two separate instances (for example, one for a custom database), you can use named apps.

This approach keeps your global configuration minimal and defers the specific setup (such as for the database) until it’s really needed, aligning with your app’s implementation and requirements.

danilipari avatar Feb 10 '25 01:02 danilipari