Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup Firebase Cloud Messaging v9 in React?

I'm having trouble setting up my firebase environment in React. I'm going through the firebase documentation, but I can't seem to get the first step of getting permission correct.

I tried looking everywhere to fix these errors, but all attempts failed. Please help!

Errors:

Service worker registration failed, error: TypeError: Failed to register a ServiceWorker for scope ('http://localhost:8080/') with script ('http://localhost:8080/firebase-messaging-sw.js'): A bad HTTP response code (404) was received when fetching the script.
An error occurred while retrieving token.  FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope ('http://localhost:8080/firebase-cloud-messaging-push-scope') with script ('http://localhost:8080/firebase-messaging-sw.js'): A bad HTTP response code (404) was received when fetching the script. (messaging/failed-service-worker-registration).

Code:

src/index.js

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('../firebase-messaging-sw.js')
  .then(function(registration) {
    console.log('Registration successful, scope is:', registration.scope);
  }).catch(function(err) {
    console.log('Service worker registration failed, error:', err);
  });
}
src/firebase.js

import { initializeApp } from "firebase/app";
import { getMessaging, getToken } from "firebase/messaging";

const firebaseApp = initializeApp({
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
});

const messaging = getMessaging(firebaseApp);
    
export const fetchToken = async (setToken) => {
  await getToken(messaging, { vapidKey: KEY_PAIR }).then((currentToken) => {
    if (currentToken) {
      setToken(currentToken)
    } else {
      console.log('No registration token available. Request permission to generate one.');
    }
  }).catch((err) => {
    console.log('An error occurred while retrieving token. ', err);
  });
}
public/firebase-messaging-sw.js

import { initializeApp } from "firebase/app";
import { getMessaging, onBackgroundMessage } from "firebase/messaging/sw";

const firebaseApp = initializeApp({
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
  measurementId: ""
});

const messaging = getMessaging(firebaseApp);

onBackgroundMessage(messaging, (payload) => {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  const notificationTitle = 'Background Message Title';
  const notificationOptions = {
    body: 'Background Message body.',
    icon: ''
  };

  self.registration.showNotification(notificationTitle, notificationOptions);
});
like image 594
GcodeG01 Avatar asked May 31 '26 11:05

GcodeG01


1 Answers

so I did this a few months ago and it worked for me, it should for you as well...

First you need to register de service worker to ger this running so in your index.js you can do the following:

// IMPORTS... 

if ("serviceWorker" in navigator) {
  navigator.serviceWorker
    .register("../firebase-messaging-sw.js")
    .then(function (registration) {
      console.log("Registration successful, scope is:", registration.scope);
    })
    .catch(function (err) {
      console.log("Service worker registration failed, error:", err);
    });
}

const dashboard = (
  <Provider store={MyStore}>
    <PersistGate loading={null} persistor={persistor}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </PersistGate>
  </Provider>
);

ReactDOM.render(dashboard, document.getElementById("root"));
reportWebVitals();

Then the sw firebase register looks like this:

importScripts("https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging-compat.js");

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

const isSupported = firebase.messaging.isSupported();
if (isSupported) {
  const messaging = firebase.messaging();
  messaging.onBackgroundMessage(({ notification: { title, body, image } }) => {
    self.registration.showNotification(title, {
      body,
      icon: image || "/assets/icons/icon-72x72.png",
    });
  });
}

It is important to have a config file for firebase: firebase.js

import { initializeApp } from "firebase/app";
import { getMessaging, getToken } from "firebase/messaging";

const firebaseConfig = {
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSENGER_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
};

const firebaseApp = initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
export { firebaseApp };


export const fetchToken = async (setToken) => {
  await getToken(messaging, {
    vapidKey: "KEY",
  })
    .then((currentToken) => {
      if (currentToken) {
        // setToken(currentToken);
        console.log("currentToken: ", currentToken);
      } else {
        console.log("No registration token available. Request permission to generate one.");
      }
    })
    .catch((err) => {
      console.log("An error occurred while retrieving token. ", err);
    });
};

After these files configures you can call the fetchToken function from a useEffect inside your main file/navigator/etc and then you can use the onMessage hook/function from firebase/messaging itself

like image 175
Carlos Yanes Avatar answered Jun 01 '26 23:06

Carlos Yanes