question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

No version specified and unable to automatically determine one With 14.5.10

See original GitHub issue

Current Behavior

Application doesn’t build correctly and produces warnings in terminal and errors in browser console when importing certain libraries and running app configured for Module Federation.

main.ts:1 Error: Unsatisfied version 0 from host of shared singleton module firebase/app (required ^9.9.0)

image

Expected Behavior

The application should compile and run as expected.

Steps to Reproduce

  1. Clone https://github.com/vdiaz1130/nx_mf_firebase_import_issue
  2. Run pnpm i
  3. Serve app pnpm start
  4. Note warnings and errors in terminal window.

Failure Logs

Configure dependencies in package.json:

    "dependencies": {
      "firebase": "^9.9.0",
      "firebase-admin": "^11.0.0",
      "firebase-functions": "^3.22.0",
      "passport-firebase-jwt": "^1.2.1",
      "@angular/fire": "^7.4.1",
      "@google-cloud/firestore": "^5.0.2",
      "@google-cloud/language": "^5.0.0",
      "@google-cloud/storage": "^6.2.3",
      "@google-cloud/vision": "^2.4.2",
      "rxfire": "^6.0.3",
      ...
    },
    "devDependencies": {
      "@firebase/app": "^0.7.31",
      "@firebase/rules-unit-testing": "^2.0.2",
      "@google-cloud/functions-framework": "^3.1.2",
      "@types/firebase": "^3.2.1",
      "firebase-functions-test": "^2.2.0",
      ...
    }

Add snippet below in any library project:

    import { DocumentSnapshot } from '@angular/fire/compat/firestore';
    import { OrderByDirection, WhereFilterOp } from 'firebase/firestore';

    export interface WhereCondition {
      field: string;
      operator: WhereFilterOp;
      value: string | number;
    }

    export interface OrderByCondition {
      field: string;
      order?: OrderByDirection;
    }

    export interface FirestoreQuery<T> {
      limit?: number;
      startAt?: number | string | DocumentSnapshot<T>;
      startAfter?: number | string | DocumentSnapshot<T>;
      endAt?: number | DocumentSnapshot<T>;
      endBefore?: number | DocumentSnapshot<T>;
      orderBy?: OrderByCondition[];
      where?: WhereCondition[];
    }

Add AngularFire Module (see repo):

    import { isDevMode, NgModule } from '@angular/core';

    import {
      APP_NAME,
      APP_VERSION,
      DEBUG_MODE as ANALYTICS_DEBUG_MODE,
      ScreenTrackingService,
      UserTrackingService,
      COLLECTION_ENABLED,
    } from '@angular/fire/compat/analytics';
    import { SETTINGS as FIRESTORE_SETTINGS } from '@angular/fire/compat/firestore';
    import { USE_DEVICE_LANGUAGE } from '@angular/fire/compat/auth';
    import { SERVICE_WORKER, VAPID_KEY } from '@angular/fire/compat/messaging';
    import {
      SETTINGS as REMOTE_CONFIG_SETTINGS,
      DEFAULTS as REMOTE_CONFIG_DEFAULTS,
    } from '@angular/fire/compat/remote-config';
    import { PerformanceMonitoringService } from '@angular/fire/compat/performance';
    import { AngularFireAuthGuardModule } from '@angular/fire/compat/auth-guard';

    import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
    import { connectFunctionsEmulator, FunctionsModule, getFunctions, provideFunctions } from '@angular/fire/functions';
    import {
      connectFirestoreEmulator,
      getFirestore,
      provideFirestore,
      enableMultiTabIndexedDbPersistence,
    } from '@angular/fire/firestore';
    import { connectDatabaseEmulator, getDatabase, provideDatabase } from '@angular/fire/database';
    import { connectStorageEmulator, getStorage, provideStorage } from '@angular/fire/storage';
    import { getRemoteConfig, provideRemoteConfig } from '@angular/fire/remote-config';
    import { getAnalytics, provideAnalytics } from '@angular/fire/analytics';
    import { getMessaging, provideMessaging } from '@angular/fire/messaging';
    import { getPerformance, providePerformance } from '@angular/fire/performance';
    import { getApp } from '@angular/fire/app';
    import {
      initializeAuth,
      browserPopupRedirectResolver,
      connectAuthEmulator,
      indexedDBLocalPersistence,
      provideAuth,
    } from '@angular/fire/auth';
    // import { initializeAppCheck, provideAppCheck, ReCaptchaV3Provider } from '@angular/fire/app-check';

    import { BrowserModule } from '@angular/platform-browser';

    const environment = {
      useEmulators: true,
      firebase: {
        apiKey: 'OeRXXXK7S_x_5rpQUu1XXXZMWyAXXXAIzatE',
        appId: '1:31401XXX732:web:ff29faXXX6595dXXX9c5',
        authDomain: 'XXX.firebaseapp.com',
        databaseURL: 'https://XXX.firebaseio.com',
        measurementId: 'G-7GXXXPWD0',
        messagingSenderId: '3571XXX61632',
        projectId: 'XXX',
        storageBucket: 'XXX.appspot.com',
      }
    }

    let resolvePersistenceEnabled: (enabled: boolean) => void;

    export const persistenceEnabled = new Promise<boolean>((resolve) => {
      resolvePersistenceEnabled = resolve;
    });

    @NgModule({
      imports: [
        BrowserModule,
        AngularFireAuthGuardModule,
        FunctionsModule,

        provideRemoteConfig(() => getRemoteConfig()),
        provideAnalytics(() => getAnalytics()),
        provideMessaging(() => getMessaging()),
        providePerformance(() => getPerformance()),
        provideAuth(() => {
          const auth = initializeAuth(getApp(), {
            persistence: indexedDBLocalPersistence,
            popupRedirectResolver: browserPopupRedirectResolver,
          });
          if (environment.useEmulators) {
            connectAuthEmulator(auth, 'http://localhost:9099', { disableWarnings: true });
          }
          return auth;
        }),
        // provideAppCheck(() =>  {
        //   const provider = new ReCaptchaV3Provider(environment.recaptcha3SiteKey);
        //   return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true });
        // }),

        provideFirebaseApp(() => initializeApp(environment.firebase)),
        provideFirestore(() => {
          const firestore = getFirestore();
          if (environment.useEmulators) {
            connectFirestoreEmulator(firestore, 'localhost', 8080);
          }
          enableMultiTabIndexedDbPersistence(firestore).then(
            () => resolvePersistenceEnabled(true),
            () => resolvePersistenceEnabled(false),
          );
          return firestore;
        }),
        provideDatabase(() => {
          const database = getDatabase();
          if (environment.useEmulators) {
            connectDatabaseEmulator(database, 'localhost', 9000);
          }
          return database;
        }),
        provideStorage(() => {
          const storage = getStorage();
          if (environment.useEmulators) {
            connectStorageEmulator(storage, 'localhost', 9199);
          }
          return storage;
        }),
        provideFunctions(() => {
          const functions = getFunctions();
          if (environment.useEmulators) {
            connectFunctionsEmulator(functions, 'localhost', 5001);
          }
          return functions;
        }),
      ],

      providers: [
        UserTrackingService,
        ScreenTrackingService,
        PerformanceMonitoringService,
        { provide: FIRESTORE_SETTINGS, useValue: { ignoreUndefinedProperties: true } },
        { provide: ANALYTICS_DEBUG_MODE, useValue: true },
        { provide: COLLECTION_ENABLED, useValue: true },
        { provide: REMOTE_CONFIG_SETTINGS, useFactory: () => (isDevMode() ? { minimumFetchIntervalMillis: 10_000 } : {}) },
        { provide: REMOTE_CONFIG_DEFAULTS, useValue: { background_color: 'red' } },
        { provide: USE_DEVICE_LANGUAGE, useValue: true },
        // { provide: VAPID_KEY, useValue: environment.vapidKey },
        {
          provide: SERVICE_WORKER,
          useFactory: () =>
            (typeof navigator !== 'undefined' &&
              navigator.serviceWorker?.register('firebase-messaging-sw.js', { scope: '__' })) ||
            undefined,
        },
        { provide: APP_VERSION, useValue: '0.0.0' },
        { provide: APP_NAME, useValue: 'deez.io' },
      ],
    })
    export class AngularFireModule { }

Import AngularFire module in host application:

    @NgModule({
      declarations: [AppComponent],
      imports: [
        BrowserModule,
        AngularFireModule, // <--
        RouterModule.forRoot(
          [
            ...
          ],
          { initialNavigation: 'enabledBlocking' }
        ),
      ],
      providers: [],
      bootstrap: [AppComponent],
    })
    export class AppModule {}

Environment

 >  NX   Report complete - copy this into the issue template

   Node : 16.9.1
   OS   : darwin x64
   pnpm : 7.9.5

   nx : 14.5.10
   @nrwl/angular : 14.5.7
   @nrwl/cypress : 14.5.10
   @nrwl/detox : Not Found
   @nrwl/devkit : 13.1.3
   @nrwl/eslint-plugin-nx : 14.5.10
   @nrwl/express : Not Found
   @nrwl/jest : 14.5.10
   @nrwl/js : 14.5.7
   @nrwl/linter : 14.5.10
   @nrwl/nest : 14.5.7
   @nrwl/next : Not Found
   @nrwl/node : 14.5.7
   @nrwl/nx-cloud : 14.6.0
   @nrwl/nx-plugin : Not Found
   @nrwl/react : Not Found
   @nrwl/react-native : Not Found
   @nrwl/schematics : Not Found
   @nrwl/storybook : 14.5.7
   @nrwl/web : 14.5.7
   @nrwl/workspace : 14.5.10
   typescript : 4.7.4
   ---------------------------------------
   Local workspace plugins:
   ---------------------------------------
   Community plugins:
   	 @ngneat/transloco: 4.0.0
   	 @nguniversal/express-engine: 13.1.1
   	 angular-calendar: 0.29.0
   	 @nguniversal/builders: 13.1.1
   	 @ngxs/schematics: 0.0.1-alpha.5

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:24 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
Coly010commented, Oct 14, 2022

I’ve taken a deeper look at this, and it looks like there may be an issue in the ModuleFederationPlugin itself.

I have a workaround in the meantime.

In each of your module-federation.config.js files, add the following to the config that is exported:

shared: (libraryName, config) => {
    if (libraryName.startsWith('firebase')) {
      return {
        ...config,
        strictVersion: false,
      };
    }
  },

You can use as many if statements as you need for the packages you need to apply the strictVersion: false to.

So your host’s module-federation.config.js should look like this:

module.exports = {
  name: 'host',
  remotes: ['cart', 'shop', 'about'],
  shared: (libraryName, config) => {
    if (libraryName.startsWith('firebase')) {
      return {
        ...config,
        strictVersion: false,
      };
    }
  },
};

and your remotes should look like this:

module.exports = {
  name: 'cart',
  exposes: {
    './Module': 'apps/cart/src/app/remote-entry/entry.module.ts',
  },
  shared: (libraryName, config) => {
    if (libraryName.startsWith('firebase')) {
      return {
        ...config,
        strictVersion: false,
      };
    }
  },
};

As there is a workaround for this, I’m going to close this issue and I’ll see if I can get this fixed in the MFP repo.

1reaction
keaston67commented, Oct 4, 2022

Hi, thanks for re-directing me to this. We’re really impressed with Nx and keen to complete our upgrade to Nx 14 / angular 14 which has stalled as we’ve run up against this issue with apollo & firebase. Any guidance you can provide around a timeframe for resolving this or a workaround would be greatly appreciated. Thanks for your help.

Read more comments on GitHub >

github_iconTop Results From Across the Web

reactjs - Luxon error - "No version specified and unable to ...
I am using webpack with react and module federation and share components between. But one of the dependency packages gives warning/error ...
Read more >
Angular MFE No version specified and unable to determine one
No version in description file (usually package.json). Add version to description file, or manually specify version in shared config. shared ...
Read more >
Pitfalls with Module Federation and Angular
"No required version specified" and Secondary Entry Points ... No required version specified and unable to automatically determine one.
Read more >
ModuleFederationPlugin - webpack
There are three ways to specify the versions of shared libraries. ... is only needed when the package name can't be automatically determined...
Read more >
@angular-architects/module-federation - npm
Latest version: 15.0.2, last published: a month ago. ... warning No required version specified and unable to automatically determine one, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found