web-dev-qa-db-fra.com

Erreur AngularFire uniquement lorsque ng serve --prod

J'ai une application Angular 8, utilisant le package npm Angular Firebase (https://github.com/angular/angularfire2) et lorsque je crée l'application avec la commande CLI Angular CLI ng build --prod et déployer sur mon hébergement, j'obtiens le suivant Chrome Console du navigateur:

TypeError: Object(...)(...).auth is not a function

Si je construis à la place avec la commande ng build --prod --optimization=false l'erreur ne se produit pas.

Quelque chose avec Angular Option de génération CLI ng optimization définie sur true est à l'origine de l'erreur de package AngularFire2 npm.

Je ne sais pas comment déboguer davantage ce problème. Voici mon fichier package.json:

    {
  "name": "bigmoenyshot",
  "version": "8.0.0",
  "license": "https://themeforest.net/licenses/terms/regular",
  "scripts": {
    "ng": "ng",
    "serve": "ng serve",
    "serveProd": "node --max_old_space_size=8048 ./node_modules/@angular/cli/bin/ng serve --prod --optimization=true",
    "build": "ng build --prod=true --aot=true --extractCss=true --optimization=true",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "deploy": "ng build --prod=true --aot=true --extractCss=true --optimization=false && firebase deploy"
  },
  "private": true,
  "dependencies": {
    "@agm/core": "1.0.0-beta.2",
    "@angular/animations": "8.0.0",
    "@angular/cdk": "8.0.1",
    "@angular/common": "8.0.0",
    "@angular/compiler": "8.0.0",
    "@angular/core": "8.0.0",
    "@angular/fire": "^5.2.1",
    "@angular/flex-layout": "8.0.0-beta.26",
    "@angular/forms": "8.0.0",
    "@angular/material": "8.0.1",
    "@angular/material-moment-adapter": "^8.0.2",
    "@angular/platform-browser": "8.0.0",
    "@angular/platform-browser-dynamic": "8.0.0",
    "@angular/router": "8.0.0",
    "@ngu/carousel": "1.5.4",
    "@ngx-translate/core": "10.0.1",
    "@ngx-translate/http-loader": "3.0.1",
    "@swimlane/ngx-datatable": "15.0.2",
    "angular-calendar": "0.26.4",
    "angular-in-memory-web-api": "0.8.0",
    "angular-star-rating": "4.0.0-beta.3",
    "chart.js": "2.5.0",
    "classlist.js": "1.1.20150312",
    "core-js": "2.4.1",
    "css-star-rating": "1.2.4",
    "date-fns": "1.28.5",
    "echarts": "4.2.1",
    "firebase": "^6.2.4",
    "flag-icon-css": "3.3.0",
    "hammerjs": "2.0.8",
    "highlight.js": "9.15.6",
    "hopscotch": "0.3.1",
    "install": "0.12.2",
    "moment": "2.24.0",
    "ng2-charts": "2.2.2",
    "ng2-dragula": "2.1.1",
    "ng2-file-upload": "1.3.0",
    "ng2-validation": "4.2.0",
    "ngx-color-picker": "7.5.0",
    "ngx-echarts": "4.1.1",
    "ngx-pagination": "3.2.1",
    "ngx-perfect-scrollbar": "^8.0.0",
    "ngx-quill": "4.8.0",
    "npm": "6.9.0",
    "perfect-scrollbar": "1.4.0",
    "quill": "1.3.6",
    "rxjs": "6.5.2",
    "rxjs-compat": "6.1.0",
    "web-animations-js": "github:angular/web-animations-js#release_pr208",
    "zone.js": "~0.9.1"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.800.6",
    "@angular-devkit/core": "7.3.8",
    "@angular/cli": "8.0.2",
    "@angular/compiler-cli": "8.0.0",
    "@angular/language-service": "8.0.0",
    "@types/hopscotch": "0.2.30",
    "@types/jasmine": "2.5.38",
    "@types/node": "6.0.60",
    "codelyzer": "^5.0.1",
    "copy-webpack-plugin": "4.3.0",
    "enhanced-resolve": "3.3.0",
    "jasmine-core": "~2.5.2",
    "jasmine-spec-reporter": "~3.2.0",
    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "~0.2.0",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "~0.2.2",
    "node-sass": "^4.12.0",
    "protractor": "~5.1.0",
    "ts-node": "2.0.0",
    "tslint": "4.5.0",
    "TypeScript": "3.4.5"
  }
}

Et voici où j'importe la Lib AngularFire2:

import { Injectable } from '@angular/core';
import { AngularFireAuth } from "@angular/fire/auth";
import { Observable } from 'rxjs';
import { tap, map, take } from 'rxjs/operators';
import { Router } from '@angular/router';
import { User, auth } from 'firebase/app';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  user: Observable<User>

  constructor(
    private firBase: AngularFireAuth,
    private router: Router // Inject Firebase auth service
  ) {
    this.user = this.firBase.authState;
  }

  isLoggedIn(redirectUrl: string, isLoggedInRedirect?: string): Observable<boolean> {
    console.log('AuthService.isLoggedIn'); return this.user.pipe(
      take(1),
      map(authState => !!authState),
      tap(authenticated => {
        if (!authenticated) {
          console.log('user not authenticated');
          this.router.navigate([redirectUrl]);
          return;
        }
        console.log('user Authenticated');
        if (isLoggedInRedirect) {
          this.router.navigate([isLoggedInRedirect]);
        }
      })
    );
  }

  getDisplayName(): string {
    return this.firBase.auth.currentUser.displayName;
  }

  // Sign up with email/password
  async signUp(email: string, password: string) {
    try {
      const result = await this.firBase.auth.createUserWithEmailAndPassword(email, password);
      console.log("successfully registered!");
      console.log(result.user);
    }
    catch (error) {
      console.error(error.message);
    }
  }

  // Sign in with email/password
  async signIn(email: string, password: string, rememberMe: boolean): Promise<string> {
    let session = 'session'; //only persist in the current session or tab, and will be cleared when the tab or window in which the user authenticated is closed

    if (rememberMe) {
      session = 'local'; //state will be persisted even when the browser window is closed or the activity
    }

    console.log('persistence type', session);
    try {
      const _ = await this.firBase.auth.setPersistence(session);
      const result = await this.firBase.auth.signInWithEmailAndPassword(email, password);
      console.log('signin success');
      return 'success';
    }
    catch (error) {
      console.error(error.message);
      return error.message;
    }
  }

  async signOut() {
    try {
      const _ = await this.firBase.auth.signOut();
      this.user = this.firBase.authState;
      console.log('signOut complete, currentUser', this.firBase.auth.currentUser);
    }
    catch (error) {
      console.error(error.message);
    }
  }

  async forgotPassword(email: string): Promise<string> {
    try {
      await this.firBase.auth.sendPasswordResetEmail(email);
      return 'Reset Email Sent';
    }
    catch (error) {
      console.error(error.message);
      return error.message;
    }
  }
}

Et voici mon app.module:

import { NgModule, ErrorHandler } from '@angular/core';
import { RouterModule } from '@angular/router';
import { BrowserModule, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { GestureConfig } from '@angular/material';
import {
  PerfectScrollbarModule,
  PERFECT_SCROLLBAR_CONFIG,
  PerfectScrollbarConfigInterface
} from 'ngx-perfect-scrollbar';


import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './shared/inmemory-db/inmemory-db.service';

import { rootRouterConfig } from './app.routing';
import { SharedModule } from './shared/shared.module';
import { AppComponent } from './app.component';

import { HttpClient, HttpClientModule } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { ErrorHandlerService } from './shared/services/error-handler.service';
import { SessionsModule } from './views/sessions/sessions.module';

import { AngularFireModule } from '@angular/fire';
//import { AngularFirestoreModule } from '@angular/fire/firestore';
import { environment } from '../environments/environment';
import { StartComponent } from './start.component';

// AoT requires an exported function for factories
export function HttpLoaderFactory(httpClient: HttpClient) {
  return new TranslateHttpLoader(httpClient);
}

const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
  suppressScrollX: true
};

@NgModule({
  imports: [
    SessionsModule,
    BrowserModule,
    BrowserAnimationsModule,
    SharedModule,
    AngularFireModule.initializeApp(environment.firebase),
    //AngularFirestoreModule,
    HttpClientModule,
    PerfectScrollbarModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    }),
    InMemoryWebApiModule.forRoot(InMemoryDataService, { passThruUnknownUrl: true }),
    RouterModule.forRoot(rootRouterConfig, { useHash: true, enableTracing: false })
  ],
  declarations: [AppComponent, StartComponent],
  providers: [
    { provide: ErrorHandler, useClass: ErrorHandlerService },
    { provide: HAMMER_GESTURE_CONFIG, useClass: GestureConfig },
    { provide: PERFECT_SCROLLBAR_CONFIG, useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
11
Brian Ogden

Ce n'est pas la réponse complète, c'est juste ma recherche. Ce que je mets ici, j'espère que ça aide quelqu'un.

Cochez cette commande

node --max-old-space-size=8000 ./node_modules/@angular/cli/bin/ng build --prod --aot=false --optimization=true --sourceMap=false --buildOptimizer=false

Commentaire: Pouvez-vous s'il vous plaît! supprimer le drapeau AOT ou le rendre faux?

Référence: https://github.com/angular/angular-cli/issues/14666#issuecomment-507057022


buildOptimizer ne fonctionne plus

--buildOptimizer=false

Référence: https://github.com/angular/angular-cli/issues/10658#issuecomment-387296781

Référence: https://github.com/angular/angular-cli/issues/10655#issuecomment-449319049


  • --source-map générer une application 10% plus petite

Référence: https://github.com/angular/angular-cli/issues/11129#issuecomment-396274621


  • définir la cible sur es5, construire la cible es2015 ont ces problèmes

Référence: https://github.com/datorama/akita/issues/179#issuecomment-47250512

Référence: https://github.com/angular/angular-cli/issues/7799#issuecomment-387167797

1
Utkarsh Dubey

Eu le même problème avec AngularFireFunctions. Géré pour le résoudre en ajoutant AngularFireFunctionsModule à mon app.module.ts. Activez simplement sourceMaps pour votre génération de prod, afin de pouvoir déboguer la bibliothèque réellement endommagée. Il s'avère que sans le module, tout fonctionnera bien en développement, mais lorsque vous construisez avec --prod flag optimizer supprime des parties du code, il ne devrait pas et il reste des extrémités libres.

1
V Djuric

Résolu cela en important les dépendances Firebase que j'utilisais sur le composant avec erreur, vous pouvez faire quelque chose comme ça:

import * as firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/storage';
import 'firebase/firestore';
import { environment } from '../../../environments/environment';

constructor(
    private afAuth: AngularFireAuth,
    private afFirestore: AngularFirestore,
    private afStorage: AngularFireStorage
  ) {
    try {
      firebase.app();
    } catch (err) {
      firebase.initializeApp(environment.firebaseConfig);
    }
}

N'oubliez pas de placer vos configurations Firebase dans votre fichier d'environnement

0
Roederick

Dans mon cas, avoir AngularFireAuthModule et AngularFirestoreModule dans app.module.ts a fonctionné depuis que j'utilisais les deux dans mon application.

imports: [
    ...
    AngularFireAuthModule,
    AngularFirestoreModule,
    ...],
0
Claudio Teles

selon la réponse de @jamesdaniels this

npm install rxjs@6 rxjs-compat@6 --save

Cela a résolu le problème.

et voici votre solution Credit @Biswajit

0
Chanaka Weerasinghe

J'ai eu le même problème. Revenir à

"@angular/fire": "~5.1.0",

résolu le problème, bien qu'il y ait des avertissements sur les incompatibilités de version avec d'autres packages (pas de compilation ou d'erreurs d'exécution).

0
Marcos