admin管理员组

文章数量:1302904

I'm trying to integrate firebase messaging into my NextJS web app but getting errors that potentially look like they're ing from the serverside. To get registrations working in _app.tsx I do the following:

  useEffect(() => {
    if ("serviceWorker" in navigator) {
      window.addEventListener("load", function () {
        const config = process.env.NEXT_PUBLIC_FIREBASE;
        navigator.serviceWorker.register("/firebase-messaging-sw.js?firebaseConfig=" + Buffer.from(config).toString('base64'), {
          type: 'module'
        }).then(
          function (registration) {
            console.log("Service Worker registration successful with scope: ", registration.scope);
          },
          function (err) {
            console.log("Service Worker registration failed: ", err);
          }
        );
      });
    }
  }, [])

Where NEXT_PUBLIC_FIREBASE is the firebase config object.

Then in public/firebase-messaging-sw.js I have this:

import { initializeApp } from ".8.1/firebase-app.js";
import { getMessaging } from ".8.1/firebase-messaging.js";

const swScriptUrl = new URL(self.location);

const base64Config = swScriptUrl.searchParams.get('firebaseConfig')
let decoded = atob(base64Config);

const firebaseConfig = JSON.parse(decoded);
const app = initializeApp(firebaseConfig);


// Retrieve an instance of Firebase Messaging so that it can handle background
const messaging = getMessaging(app);

When getMessaging is called I get this error:

Uncaught SyntaxError: Cannot use import statement outside a module (at firebase-messaging-sw.js:1:1)
index.esm2017.js?f614:823 Uncaught (in promise) FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope ('http://localhost:3000/firebase-cloud-messaging-push-scope') with script ('http://localhost:3000/firebase-messaging-sw.js'): ServiceWorker script evaluation failed (messaging/failed-service-worker-registration).
    at registerDefaultSw (index.esm2017.js?f614:823:1)
    at async updateSwReg (index.esm2017.js?f614:847:1)
    at async getToken$1 (index.esm2017.js?f614:910:1)
    at async FirebaseMessagingWeb.getToken (web.js?00d2:24:1)
registerDefaultSw @ index.esm2017.js?f614:823
Promise.then (async)
asyncGeneratorStep @ ios-notification.ts?89f7:2
_next @ ios-notification.ts?89f7:2
eval @ ios-notification.ts?89f7:2
eval @ ios-notification.ts?89f7:2
addListeners @ ios-notification.ts?89f7:4
eval @ notification-context.tsx?dccb:38
Promise.then (async)
registerForNotifications @ notification-context.tsx?dccb:37
registerForNotifications @ notification-context.tsx?dccb:62
onClick @ profile-box.tsx?a1b7:280
callCallback @ react-dom.development.js?ac89:4161
invokeGuardedCallbackDev @ react-dom.development.js?ac89:4210
invokeGuardedCallback @ react-dom.development.js?ac89:4274
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js?ac89:4288
executeDispatch @ react-dom.development.js?ac89:9038
processDispatchQueueItemsInOrder @ react-dom.development.js?ac89:9070
processDispatchQueue @ react-dom.development.js?ac89:9083
dispatchEventsForPlugins @ react-dom.development.js?ac89:9094
eval @ react-dom.development.js?ac89:9285
batchedUpdates$1 @ react-dom.development.js?ac89:26096
batchedUpdates @ react-dom.development.js?ac89:3988
dispatchEventForPluginEventSystem @ react-dom.development.js?ac89:9284
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js?ac89:6462
dispatchEvent @ react-dom.development.js?ac89:6454
dispatchDiscreteEvent @ react-dom.development.js?ac89:6427
firebase-messaging-sw.js:1 Uncaught SyntaxError: Cannot use import statement outside a module (at firebase-messaging-sw.js:1:1)

I've checked the config object and it definitely is correct and making it to the service worker (also tried just copying the config in to no avail).

Have tried getting this to work both locally and on a https server to no avail, I've also tried a none module import which produced the same error.

I'm trying to integrate firebase messaging into my NextJS web app but getting errors that potentially look like they're ing from the serverside. To get registrations working in _app.tsx I do the following:

  useEffect(() => {
    if ("serviceWorker" in navigator) {
      window.addEventListener("load", function () {
        const config = process.env.NEXT_PUBLIC_FIREBASE;
        navigator.serviceWorker.register("/firebase-messaging-sw.js?firebaseConfig=" + Buffer.from(config).toString('base64'), {
          type: 'module'
        }).then(
          function (registration) {
            console.log("Service Worker registration successful with scope: ", registration.scope);
          },
          function (err) {
            console.log("Service Worker registration failed: ", err);
          }
        );
      });
    }
  }, [])

Where NEXT_PUBLIC_FIREBASE is the firebase config object.

Then in public/firebase-messaging-sw.js I have this:

import { initializeApp } from "https://www.gstatic./firebasejs/9.8.1/firebase-app.js";
import { getMessaging } from "https://www.gstatic./firebasejs/9.8.1/firebase-messaging.js";

const swScriptUrl = new URL(self.location);

const base64Config = swScriptUrl.searchParams.get('firebaseConfig')
let decoded = atob(base64Config);

const firebaseConfig = JSON.parse(decoded);
const app = initializeApp(firebaseConfig);


// Retrieve an instance of Firebase Messaging so that it can handle background
const messaging = getMessaging(app);

When getMessaging is called I get this error:

Uncaught SyntaxError: Cannot use import statement outside a module (at firebase-messaging-sw.js:1:1)
index.esm2017.js?f614:823 Uncaught (in promise) FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope ('http://localhost:3000/firebase-cloud-messaging-push-scope') with script ('http://localhost:3000/firebase-messaging-sw.js'): ServiceWorker script evaluation failed (messaging/failed-service-worker-registration).
    at registerDefaultSw (index.esm2017.js?f614:823:1)
    at async updateSwReg (index.esm2017.js?f614:847:1)
    at async getToken$1 (index.esm2017.js?f614:910:1)
    at async FirebaseMessagingWeb.getToken (web.js?00d2:24:1)
registerDefaultSw @ index.esm2017.js?f614:823
Promise.then (async)
asyncGeneratorStep @ ios-notification.ts?89f7:2
_next @ ios-notification.ts?89f7:2
eval @ ios-notification.ts?89f7:2
eval @ ios-notification.ts?89f7:2
addListeners @ ios-notification.ts?89f7:4
eval @ notification-context.tsx?dccb:38
Promise.then (async)
registerForNotifications @ notification-context.tsx?dccb:37
registerForNotifications @ notification-context.tsx?dccb:62
onClick @ profile-box.tsx?a1b7:280
callCallback @ react-dom.development.js?ac89:4161
invokeGuardedCallbackDev @ react-dom.development.js?ac89:4210
invokeGuardedCallback @ react-dom.development.js?ac89:4274
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js?ac89:4288
executeDispatch @ react-dom.development.js?ac89:9038
processDispatchQueueItemsInOrder @ react-dom.development.js?ac89:9070
processDispatchQueue @ react-dom.development.js?ac89:9083
dispatchEventsForPlugins @ react-dom.development.js?ac89:9094
eval @ react-dom.development.js?ac89:9285
batchedUpdates$1 @ react-dom.development.js?ac89:26096
batchedUpdates @ react-dom.development.js?ac89:3988
dispatchEventForPluginEventSystem @ react-dom.development.js?ac89:9284
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js?ac89:6462
dispatchEvent @ react-dom.development.js?ac89:6454
dispatchDiscreteEvent @ react-dom.development.js?ac89:6427
firebase-messaging-sw.js:1 Uncaught SyntaxError: Cannot use import statement outside a module (at firebase-messaging-sw.js:1:1)

I've checked the config object and it definitely is correct and making it to the service worker (also tried just copying the config in to no avail).

Have tried getting this to work both locally and on a https server to no avail, I've also tried a none module import which produced the same error.

Share edited May 15, 2022 at 14:58 meds asked May 15, 2022 at 14:47 medsmeds 23k42 gold badges171 silver badges337 bronze badges 5
  • 1 Try using importScripts to import the firebase-app and firebase-messaging scripts instead. – juliomalves Commented May 15, 2022 at 15:34
  • 1 yep tried that (importScripts("gstatic./firebasejs/9.8.1/firebase-app.js");), got another error about import Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'gstatic./firebasejs/9.8.1/firebase-app.js' failed to load. – meds Commented May 15, 2022 at 16:11
  • Are you properly adding the protocol in the URL, i.e. importScripts ("https://www.gstatic./firebasejs/9.8.1/firebase-app.js")? – juliomalves Commented May 15, 2022 at 16:14
  • 2 Yes, full URL - stackoverflow is just turning it into a link – meds Commented May 16, 2022 at 11:18
  • can use importScripts("gstatic./firebasejs/9.8.1/firebase-app-pat.js"); – Warren Commented Jul 23, 2024 at 6:26
Add a ment  | 

3 Answers 3

Reset to default 4

The same thing happened to me, the first is to use importScripts , and the second is to downgrade to 8.0.0 and change the function calls a bit. As I show you below:

   importScripts("https://www.gstatic./firebasejs/8.0.0/firebase-app.js");
   importScripts("https://www.gstatic./firebasejs/8.0.0/firebase-messaging.js");
    
    const swScriptUrl = new URL(self.location);
    
    const base64Config = swScriptUrl.searchParams.get('firebaseConfig')
    let decoded = atob(base64Config);
    
    const firebaseConfig = JSON.parse(decoded);
    const app = firebase.initializeApp(firebaseConfig);
    
    
    // Retrieve an instance of Firebase Messaging so that it can handle background
    const messaging = firebase.messaging();

This work for me

importScripts(
  'https://www.gstatic./firebasejs/9.18.0/firebase-app-pat.js'
);
importScripts(
  'https://www.gstatic./firebasejs/9.18.0/firebase-messaging-pat.js'
);

var FIREBASE_CONFIG = {
  apiKey: "...",
  authDomain: "...",
  projectId: "...",
  storageBucket: "...",
  messagingSenderId: "...",
  appId: "...",
  measurementId: "...",
};

// Initialize Firebase
firebase.initializeApp(FIREBASE_CONFIG);
const messaging = firebase.messaging();

The current newest importScripts firebase with firebase-messaging-sw.js using Next.js + next-pwa, is working for me on Windows and Android out of the box. For macOS, you need to enable Chrome notifications in the System Preferences. Note: I haven't tested iOS yet, but it should work. I hope it helps someone. Good luck

//public/firebase-messaging-sw.js

importScripts('https://www.gstatic./firebasejs/10.10.0/firebase-app-pat.js');
importScripts('https://www.gstatic./firebasejs/10.10.0/firebase-messaging-pat.js');


firebase.initializeApp({
    apiKey: "...",
    authDomain: "...",
    projectId: "...",
    storageBucket: "...",
    messagingSenderId: "...",
    appId: "...",
    measurementId: "..."
});

// firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();

messaging.onBackgroundMessage((payload) => {
    console.log(
        "[firebase-messaging-sw.js] Received background message ",
        payload
    );
    const notificationTitle = payload.notification.title;
    const notificationOptions = {
        body: payload.notification.body,
        icon: payload.notification.image,
    };

    self.registration.showNotification(notificationTitle, notificationOptions);
});

本文标签: