Angularfire: ERROR in ./node_modules/@angular/fire/messaging/messaging.js 14:40 Module parse failed: Unexpected token

Created on 16 May 2019  路  3Comments  路  Source: angular/angularfire

Version info

  • Firebase SDK version: v6.0.2
  • Firebase Product: Firebase Cloud Messaging(FCM)
  • Node: v10.8.0
  • NPM: v6.4.1
  • Angular: v6.1.10
  • Angular CLI: v6.2.7
  • @angular/fire: v5.1.3

How it occurred ?

My project use Firebase Cloud Message(FCM)
during system development, no problems were found.
But have the problem when I build to the production(ng build --prod --progress)

How to reproduce these conditions

File: package.json

{
  "name": "ng-app",
  "version": "1.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "build-prd": "ng build --prod --progress"
  },
  "private": true,
  "dependencies": {
    "@agm/core": "1.0.0-beta.4",
    "@agm/js-marker-clusterer": "1.0.0-beta.5",
    "@angular/animations": "6.1.10",
    "@angular/cdk": "6.4.7",
    "@angular/common": "6.1.10",
    "@angular/compiler": "6.1.10",
    "@angular/core": "6.1.10",
    "@angular/fire": "5.1.3",
    "@angular/flex-layout": "6.0.0-beta.17",
    "@angular/forms": "6.1.10",
    "@angular/platform-browser": "6.1.10",
    "@angular/platform-browser-dynamic": "6.1.10",
    "@angular/pwa": "0.13.9",
    "@angular/router": "6.1.10",
    "@angular/service-worker": "6.1.10",
    "@fortawesome/fontawesome-free": "5.6.0",
    "@ngx-translate/core": "10.0.2",
    "@ngx-translate/http-loader": "3.0.1",
    "@swimlane/ngx-charts": "9.0.0",
    "@swimlane/ngx-datatable": "13.1.0",
    "@types/googlemaps": "3.30.11",
    "@types/jquery": "2.0.50",
    "@types/lodash": "4.14.121",
    "angular-resize-event": "1.0.0",
    "bmz-datatable-bs4": "1.0.10",
    "bmz-js-utils": "1.4.0",
    "bootstrap": "4.1.3",
    "bootstrap-datepicker": "1.8.0",
    "bootstrap-timepicker": "0.5.2",
    "classlist.js": "1.1.20150312",
    "core-js": "2.5.7",
    "datatables.net-autofill-bs4": "2.3.3",
    "datatables.net-bs4": "1.10.19",
    "datatables.net-buttons-bs4": "1.5.4",
    "datatables.net-colreorder-bs4": "1.5.1",
    "datatables.net-fixedcolumns-bs4": "3.2.6",
    "datatables.net-fixedheader-bs4": "3.1.5",
    "datatables.net-keytable-bs4": "2.5.0",
    "datatables.net-responsive-bs4": "2.2.3",
    "datatables.net-rowgroup-bs4": "1.1.0",
    "datatables.net-rowreorder-bs4": "1.2.5",
    "datatables.net-scroller-bs4": "1.5.1",
    "datatables.net-select-bs4": "1.3.0",
    "firebase": "6.0.2",
    "floatthead": "2.1.3",
    "jquery": "1.12.4",
    "js-marker-clusterer": "1.0.0",
    "jszip": "3.1.5",
    "lodash": "4.17.11",
    "material-tooltip": "1.0.1",
    "ng-block-ui": "2.0.0",
    "ng2-google-charts": "3.5.0",
    "ng5-slider": "1.1.8",
    "ngx-bootstrap": "3.1.2",
    "ngx-contextmenu": "5.0.3",
    "ngx-mask": "7.4.2",
    "ngx-treeview": "6.0.2",
    "node-sass": "4.12.0",
    "pdfmake": "0.1.56",
    "popper.js": "1.14.5",
    "query-string": "6.2.0",
    "rx-polling": "1.0.1",
    "rxjs": "6.2.2",
    "rxjs-compat": "6.2.2",
    "select2": "4.0.6-rc.1",
    "select2-bootstrap-theme": "0.1.0-beta.10",
    "sweetalert2": "8.5.0",
    "terser": "3.14.1",
    "ts-helpers": "1.1.2",
    "update": "0.7.4",
    "web-animations-js": "2.3.1",
    "zone.js": "0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "0.13.9",
    "@angular/cli": "6.2.7",
    "@angular/compiler-cli": "6.1.10",
    "@angular/language-service": "6.1.10",
    "@types/jasmine": "2.8.12",
    "@types/jasminewd2": "2.0.6",
    "@types/node": "8.9.5",
    "codelyzer": "4.3.0",
    "concat": "1.0.3",
    "jasmine-core": "2.99.1",
    "jasmine-spec-reporter": "4.2.1",
    "karma": "3.0.0",
    "karma-chrome-launcher": "2.2.0",
    "karma-coverage-istanbul-reporter": "2.0.4",
    "karma-jasmine": "1.1.2",
    "karma-jasmine-html-reporter": "0.2.2",
    "protractor": "5.4.1",
    "ts-node": "7.0.1",
    "tslint": "5.11.0",
    "typescript": "2.9.2"
  }
}

Steps to set up and reproduce

  1. Create file: src/manifest.json and encode below.
{
    "gcm_sender_id": "103953800507"
}
  1. Create file: src/firebase-messaging-sw.js and encode below.
// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/6.0.2/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/6.0.2/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
    'messagingSenderId': '****123****'
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
  1. Change config in angular.json
"assets": [
    "src/assets",
    "src/i18n",
    "src/favicon.ico",
    "src/manifest.json",
    "src/firebase-messaging-sw.js"
],
  1. Add link tag rel manifest in index.html
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=11"/>
    <meta http-equiv="cache-control" content="no-cache"/>
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <link rel="manifest" href="/manifest.json">
    <title>Project</title>
    <base href="">
</head>
<body>
<div class="container-fluid" id="page-wrapper-this">
    <app-root></app-root>
</div>
</body>
</html>
  1. Add firebase config in environments (environment.ts and environment.prod.ts)
export const environment = {
    ...
    ...
    firebase: {
        apiKey: "***O8qR*********",
        authDomain: "******.firebaseapp.com",
        databaseURL: "https://******.firebaseio.com",
        projectId: "message-***",
        storageBucket: "message-******.appspot.com",
        messagingSenderId: "911******",
    }
};
  1. app.module.ts
imports: [
    ...
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireAuthModule,
    AngularFireMessagingModule
],
  1. messaging.service.service.ts
import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';
import {AngularFireAuth} from '@angular/fire/auth';
import {AngularFireMessaging} from '@angular/fire/messaging';
import {take} from 'rxjs/operators';
import {AppProfileService} from '../app-profile/app-profile.service';
import {HttpClient, HttpParams} from '@angular/common/http';
import {SuccessResponse} from '../common-interface/SuccessResponse';

@Injectable({
    providedIn: 'root'
})
export class MessagingService {

    servicePath = '/api';
    currentMessage = new BehaviorSubject(null);

    constructor(
        private angularFireAuth: AngularFireAuth,
        private angularFireMessaging: AngularFireMessaging,
        private appProfile: AppProfileService,
        private http: HttpClient) {
        this.angularFireMessaging.messaging
            .subscribe(
                (_messaging) => {
                    _messaging.onMessage = _messaging.onMessage.bind(_messaging);
                    _messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);
                }
            )
    }

    /**
     * update token in firebase database
     *
     * @param userId userId as a key
     * @param token token as a value
     */
    updateToken(userId, token) {
        // we can change this function to request our backend service
        this.angularFireAuth.authState.pipe(take(1)).subscribe(
            () => {
                const data = {};
                data[userId] = token;
                // this.angularFireDB.object('fcmTokens/').update(data)
            })
    }

    /**
     * request permission for notification from firebase cloud messaging
     *
     */
    requestPermission() {
        this.angularFireMessaging.requestToken
            .subscribe(
                (token) => {
                    console.log(this.appProfile.userProfile);
                    console.log(token);
                },
                (err) => {
                    console.error('Unable to get permission to notify.', err);
                }
            );
    }

    /**
     * hook method when new notification received in foreground
     */
    receiveMessage() {
        this.angularFireMessaging.messages
            .subscribe(
                (payload) => {
                    console.log("new message received. ", payload);
                    this.currentMessage.next(payload);
                })
    }

    registerTokenFCM(fcmToken: string, plantNo: string) {
        const objectParams = {
            fcmToken: fcmToken,
            plantNo: plantNo
        };
        console.log(objectParams);
        const httpOptions = {
            params: new HttpParams({fromObject: objectParams})
        };
        this.http.get<SuccessResponse<any>>(this.rdsServicePath + '/fcm/register-topics', httpOptions)
            .subscribe(s => {
                console.log(s);
            });
    }
}

Debug output

* Errors in the terminal console after built. *

ERROR in ./node_modules/@angular/fire/messaging/messaging.js 14:40
Module parse failed: Unexpected token (14:40)
You may need an appropriate loader to handle this file type.
|         var _this = this;
|         if (!isPlatformServer(platformId)) {
>             var requireMessaging = from(import('firebase/messaging'));
|             this.messaging = requireMessaging.pipe(map(function () { return _firebaseAppFactory(options, nameOrConfig); }), map(function (app) { return app.messaging(); }), runOutsideAngular(zone));

Expected behavior

No error and build to production successfully.
> ng build --prod --progress

How do I fix it?

Thank you so much.

Most helpful comment

I solved the problem solution below.

Look at devDependencies

I downgrade @angular-devkit/build-angular version from 0.13.9 to 0.8.9

I think @angular/fire part of firebase/messaging not compatible build by TerserPlugin

Because version 0.13.9 using build by TerserPlugin, but version 0.8.9 using build by UglifyJSPlugin

image

I'm not sure this is the best way but it make me able to continue to work

Everyone can recommend me.

All 3 comments

I solved the problem solution below.

Look at devDependencies

I downgrade @angular-devkit/build-angular version from 0.13.9 to 0.8.9

I think @angular/fire part of firebase/messaging not compatible build by TerserPlugin

Because version 0.13.9 using build by TerserPlugin, but version 0.8.9 using build by UglifyJSPlugin

image

I'm not sure this is the best way but it make me able to continue to work

Everyone can recommend me.

Thanks for the new knowledge

I think this should be reopened. While downgrading @angular-devkit/build-angular lets my project compile, there's webpack errors in the browser at runtime:

TypeError: __webpack_require__.e is not a function
    at vendor.js:83865
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (polyfills.js:9624)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (polyfills.js:9374)
    at NgZone.push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular (vendor.js:76386)
    at new UserTrackingService (vendor.js:83864)
    at _createClass (vendor.js:80104)
    at _createProviderInstance (vendor.js:80072)
    at initNgModule (vendor.js:80005)
    at new NgModuleRef_ (vendor.js:80732)
    at createNgModuleRef (vendor.js:80721)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

fisherds picture fisherds  路  3Comments

StephenFluin picture StephenFluin  路  3Comments

adriandurran picture adriandurran  路  3Comments

avanderbergh picture avanderbergh  路  3Comments

jteplitz picture jteplitz  路  3Comments