AngularFire2 App Init in Module Conflicts with Dyn

2019-07-25 17:31发布

I have a problem due to my config data being loaded at runtime and AnuglarFire2 wanting the data in the module declaration. I can access the data via direct injection, but I cannot figure out how to get the data to AngularFireModule in my module file.

Having the data loaded at runtime is the preferred way to get configuration data to the app. So, I cannot change this process. Therefore, I need to come up with a solution to the problem.

AngualrFire2 Setup Page https://github.com/angular/angularfire2/blob/master/docs/1-install-and-setup.md

Here are my files:

** Config Data Loaded (main.ts) **

function processConfigData(config, env) {
    platformBrowserDynamic([
      {provide: "appConfig", useValue: config},
      {provide: "appEnv", useValue: env}
    ]).bootstrapModule(AppModule);
}

The config data is pulled from the server and is passed in to the app.

Then I get the data from Direct Injection.

** Config Service (app-config.service.ts)**

import { Inject, Injectable } from '@angular/core';

// Code came from: 
https://gist.github.com/fernandohu/122e88c3bcd210bbe41c608c36306db9


@Injectable()

export class AppConfig {


constructor(@Inject("appConfig") private config, @Inject("appEnv") private env) {
}

/**
 * Use to get the data found in the second file (config file)
 */
public getConfig(key: any) {
  return this.config[key];
}

/**
 * Use to get the data found in the first file (env file)
 */
public getEnv(key: any) {
  return this.env[key];
} 

At this point, I only know how to get the config data from direct injection. I cannot figure out how to get it into the module to configure AngularFire2. Here is the code AngularFire2 is recommending for setting it up:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularFireModule } from 'angularfire2';

// Must export the config
export const firebaseConfig = {
  apiKey: '<your-key>',
  authDomain: '<your-project-authdomain>',
  databaseURL: '<your-database-URL>',
  storageBucket: '<your-storage-bucket>',
  messagingSenderId: '<your-messaging-sender-id>'
};

@NgModule({
  imports: [
    BrowserModule,
    AngularFireModule.initializeApp(firebaseConfig)
  ],
  declarations: [ AppComponent ],
  bootstrap: [ AppComponent ]
})
export class AppModule {} 

Any help solving this problem is greatly appreciated.

1条回答
叼着烟拽天下
2楼-- · 2019-07-25 18:13

The call to AngularFireModule.initializeApp doesn't do anything magical, it simply returns the module along with some providers:

export class AngularFireModule {
  static initializeApp(config: FirebaseAppConfig, authConfig?: AuthConfiguration, appName?: string): ModuleWithProviders {
    return {
      ngModule: AngularFireModule,
      providers: [
        { provide: FirebaseUserConfig, useValue: config },
        { provide: FirebaseConfig, useFactory: _getDefaultFirebase, deps: [FirebaseUserConfig] },
        { provide: FirebaseAuthConfig, useValue: authConfig },
        { provide: FirebaseAppName, useValue: appName }
      ]
    }
  }
}

Note that the Firebase config is provided using the FirebaseUserConfig token.

Some of the tokens used in AngularFireModule.initializeApp are not public, so the best approach is to call AngularFireModule.initializeApp and filter the config provider from the result. The config provider can then be made available in the call to platformBrowserDynamic using the information you have obtained dynamically:

import {
  AngularFireModule,
  AuthMethods,
  AuthProviders,
  FirebaseUserConfig
} from "angularfire2";

// Call initializeApp, passing an empty config object:

const angularFireImport = AngularFireModule.initializeApp({}, {
  method: AuthMethods.Password,
  provider: AuthProviders.Password
});

// Filter the config from the providers:

angularFireImport.providers = angularFireImport.providers.filter(
  (provider: any) => provider.provide !== FirebaseUserConfig
);

@NgModule({
  bootstrap: [AppComponent],
  imports: [
    angularFireImport,
    BrowserModule,
    FormsModule
  ]
})
class AppModule {}

// Provide the Firebase config in the platformBrowserDynamic call:

function processConfigData(config, env) {

  const firebaseConfig = {
    apiKey: '<your-key from the dynamic config>',
    authDomain: '<your-project-authdomain from the dynamic config>',
    databaseURL: '<your-database-URL from the dynamic config>',
    messagingSenderId: '<your-messaging-sender-id from the dynamic config>',
    storageBucket: '<your-storage-bucket from the dynamic config>'
  };

  platformBrowserDynamic([
    { provide: "appConfig", useValue: config },
    { provide: "appEnv", useValue: env },
    { provide: FirebaseUserConfig, useValue: firebaseConfig }
  ]).bootstrapModule(AppModule);
}
查看更多
登录 后发表回答