angular / angularfire

Angular + Firebase = ❤️
https://firebaseopensource.com/projects/angular/angularfire2
MIT License
7.68k stars 2.19k forks source link

AngularFire 17.1.0 breaks - Argument of type 'EnvironmentProviders' is not assignable to parameter of type 'ImportProvidersSource' #3526

Open woutersteven opened 4 months ago

woutersteven commented 4 months ago

Version info

Angular:

Angular: 17.3.8
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, localize, material, platform-browser
... platform-browser-dynamic, platform-server, router
... service-worker

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1703.7
@angular-devkit/build-angular   17.3.7
@angular-devkit/core            17.3.7
@angular-devkit/schematics      17.3.7
@angular/cli                    17.3.7
@angular/fire                   17.1.0
@angular/pwa                    17.3.7
@schematics/angular             17.3.7
rxjs                            7.8.1
typescript                      5.4.5
zone.js                         0.14.5

Firebase:

firebase               10.12.0

AngularFire:

@angular/fire                   17.1.0

Other (e.g. Ionic/Cordova, Node, browser, operating system):

Ionic                8.1.1.

How to reproduce these conditions

Compile app with AngularFire 17.0.1 everything works, compile against 17.1.0, it results in the error message:

[ng] Error: src/main.ts:139:9 - error TS2345: Argument of type 'EnvironmentProviders' is not assignable to parameter of type 'ImportProvidersSource'.

Relevant code in main.ts

document.addEventListener('DOMContentLoaded', () => {
  bootstrapApplication(AppComponent, {
    providers: [
      Capacitor.isNativePlatform() ? provideNgxStripe(environment.stripe.publishableKey) : [],
      importProvidersFrom(
        LoggerModule.forRoot({
          serverLoggingUrl: '/api/logs',
          level: environment.loglevel,
          serverLogLevel: NgxLoggerLevel.OFF
        }),
        IonicModule.forRoot({
          animated: true,
          scrollAssist: false,
          scrollPadding: false
        }),
        ReactiveFormsModule,
        AppRoutingModule,
        ServiceWorkerModule.register('ngsw-worker.js', {
          enabled: environment.production,
          registrationStrategy: 'registerWhenStable:30000',
          scope: '/'
        }),       
        provideFirebaseApp(() => {
          const app = initializeApp(environment.firebase)
          return app;
        }),
        provideAuth(() => {
          if (Capacitor.isNativePlatform()) {
            return initializeAuth(getApp(), {
              persistence: indexedDBLocalPersistence
            });
          }
          else {
            const auth = getAuth();
            if (environment.emulation) {
              connectAuthEmulator(auth, 'http://localhost:9099');
            }
            return auth;
          }
        }),
        provideFirestore(() => {
          const firestore = getFirestore();
          if (environment.emulation) {
            connectFirestoreEmulator(firestore, 'localhost', 8080);
          }
          return firestore;
        }),
        provideMessaging(() => {
          const messaging = getMessaging();
          return messaging;
        }),
        provideStorage(() => {
          const storage = getStorage();
          if (environment.emulation) {
            connectStorageEmulator(storage, 'localhost', 9199);
          }
          return getStorage();
        }),
        provideFunctions(() => {
          const functions = getFunctions(getApp(), 'europe-west1');
          if (environment.emulation) {
            connectFunctionsEmulator(functions, 'localhost', 5001);
          }
          return functions;
        }),
        HttpClientModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useFactory: (createTranslateLoader),
            deps: [HttpClient]
          }
        }),
        NgOptimizedImage),
      {
        provide: APP_INITIALIZER,
        useFactory: languageInitializer,
        deps: [LanguageService, SplitpaneService, Router],
        multi: true
      },
      { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
      { provide: ErrorHandler, useClass: GlobalErrorHandlerService },
      {
        provide: APP_INITIALIZER,
        useFactory: (FontawesomeService: FontawesomeService) => async () => {
          await FontawesomeService.addIcons();
        },
        deps: [FontawesomeService],
        multi: true,
      },
      provideHttpClient(withInterceptorsFromDi()),
      {
        provide: HIGHLIGHT_OPTIONS,
        useValue: {
          fullLibraryLoader: () => import('highlight.js'),
          themePath: 'assets/ngx-highlightjs/atom-one-light.css'
        }
      }
    ]
  }).then(() => { })r
    .catch(err => console.log(err));
});

I can just keep using 17.0.1 for now as i don't really need the Vertex AI wrapper yet

google-oss-bot commented 4 months ago

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

jamesdaniels commented 4 months ago

Oh fun, that shouldn't have broken... sorry probably should have saved that one for v18.

You can pull the "provideFirebase" functions outside of the importProvidersFrom call and you'll be back up and running again.

woutersteven commented 4 months ago

Thank you for the fast reply, that worked!

spock123 commented 4 months ago

I'm sorry I didn't understand this - if I pull all the @angular/fire providers outside the importProvidersFrom function, and add them to the providers array directly, the error stays the same (on v18, both NG and Fire).. any help? Here is my firebase config:

import { importProvidersFrom, EnvironmentProviders, Injector } from '@angular/core';
import { provideFirebaseApp, initializeApp, getApp } from '@angular/fire/app';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { provideAuth, initializeAuth, browserPopupRedirectResolver } from '@angular/fire/auth';

import { environment } from '@environment';
import { browserLocalPersistence, browserSessionPersistence } from '@firebase/auth';

const firebaseProviders: EnvironmentProviders = importProvidersFrom([
    provideFirebaseApp(() => initializeApp(environment.firebase)),
    provideFirestore(() => getFirestore()),
    provideAuth(() =>
        initializeAuth(getApp(), {
            persistence: [browserSessionPersistence, browserLocalPersistence],
            popupRedirectResolver: browserPopupRedirectResolver
        })
    )
]);

export { firebaseProviders };
schreibse commented 4 months ago

I'm sorry I didn't understand this - if I pull all the @angular/fire providers outside the importProvidersFrom function, and add them to the providers array directly, the error stays the same (on v18, both NG and Fire).. any help? Here is my firebase config:

import { importProvidersFrom, EnvironmentProviders, Injector } from '@angular/core';
import { provideFirebaseApp, initializeApp, getApp } from '@angular/fire/app';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { provideAuth, initializeAuth, browserPopupRedirectResolver } from '@angular/fire/auth';

import { environment } from '@environment';
import { browserLocalPersistence, browserSessionPersistence } from '@firebase/auth';

const firebaseProviders: EnvironmentProviders = importProvidersFrom([
    provideFirebaseApp(() => initializeApp(environment.firebase)),
    provideFirestore(() => getFirestore()),
    provideAuth(() =>
        initializeAuth(getApp(), {
            persistence: [browserSessionPersistence, browserLocalPersistence],
            popupRedirectResolver: browserPopupRedirectResolver
        })
    )
]);

export { firebaseProviders };

simple example for app.config.ts (Angular 18).

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(appRoutes),
    provideFirebaseApp(() => initializeApp(firebaseConfig)),
    provideFirestore(() => getFirestore()),
  ],
};

As you can see, both provideFirebaseApp as well as provideFirestore are not inside the importProvidersFrom function, like required before and you are using in your example above, that was meant with "pull outside importProvidersFrom". Does this help?

spock123 commented 4 months ago

@schreibse thanks, that is what I tried but got the same issue.. I'll give it another shot.. thank you so much Is it also provideAuth that should be pulled out?

schreibse commented 4 months ago

@schreibse thanks, that is what I tried but got the same issue.. I'll give it another shot.. thank you so much Is it also provideAuth that should be pulled out?

yes, everything related to firebase has to be pulled out of importProvidersFrom.

It might help to read the steps/code of the AngularFire web codelab

mjgul commented 4 months ago

It was working fine with angular < 18, I just upgraded to angular 18 and facing this error:

[ERROR] TS2345: Argument of type 'EnvironmentProviders' is not assignable to parameter of type 'ImportProvidersSource'. [plugin angular-compiler] [ng] [ng] src/main.ts:63:47: [ng] 63 │ ...orRoot(), provideFirebaseApp(() => initializeApp(environment.fi...

spock123 commented 4 months ago

@schreibse I am on ng18 btw

schreibse commented 4 months ago

It was working fine with angular < 18, I just upgraded to angular 18 and facing this error:

[ERROR] TS2345: Argument of type 'EnvironmentProviders' is not assignable to parameter of type 'ImportProvidersSource'. [plugin angular-compiler] [ng] [ng] src/main.ts:63:47: [ng] 63 │ ...orRoot(), provideFirebaseApp(() => initializeApp(environment.fi...

yes, hence this issue. Did you try the proposed solution It works fine after extracting everything firebase related from importProvidersFrom(...)

@schreibse I am on ng18 btw Me as well! I created a new angular workspace with cli and configured firebase. From package.json:

"@angular/animations": "^18.0.0",
"@angular/common": "^18.0.0",
"@angular/compiler": "^18.0.0",
"@angular/core": "^18.0.0",
"@angular/fire": "^18.0.1",
"@angular/forms": "^18.0.0",
"@angular/platform-browser": "^18.0.0",
"@angular/platform-browser-dynamic": "^18.0.0",
"@angular/router": "^18.0.0",

After I encountered the error I found this issue with the working solution. Please share your app.config.ts as well as separate provider files (from your code snippet above it seems like you have one for firebase)

spock123 commented 4 months ago

Hey guys, I managed now by pulling the calls out, as suggested. Previously I got errros when doing so but it works now, thank you all for good suggestions.

Edit: I see now that the error I had was fixed with the newly added version 18.0.1 https://github.com/angular/angularfire/issues/3536

spock123 commented 4 months ago

@schreibse it seems to be working with @angular/fire 18.0.1