DEV Community

Sujit M
Sujit M

Posted on

FCM Integration in react and node (Part -1)

So, I have surfed a web for quite some time for FCM and gone through documentation as well but i could not found the one stop solution.

Here we go.

Integration with React

This is quite simple and straight forward.

I believe you do have the project ready if not

npx create-react-app fcm-client

Here is the tricky part - To work with notification you need a device token APN token.(App registration on specific device) for that we need to convert your app into a PWA. But, create-react-app has removed the service workers from the initial repo. To use service workers

npx create-react-app fcm-client --template cra-template-pwa

refer https://create-react-app.dev/docs/making-a-progressive-web-app/

This will create app with service worker.

Once this is complete go to firebase console and set up a new project (Assuming you will do it on your own)

Go to project settings->cloud messaging->web push certificate
and generate the key pair (will be needing to generate device token)

firebase setting page

npm install bootstrap react-bootstrap

Go to App.js and paste below code
This will create a bootstrap toaster to display

import logo from './logo.svg';
import './App.css';
import {useState} from 'react';
import {Button, Row, Col, Toast} from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

function App() {

const [show, setShow] = useState(false);


  return (
    <div className="App">
        <Toast onClose={() => setShow(false)} show={show} delay={3000} autohide animation style={{
          position: 'absolute',
          top: 20,
          right: 20,
        }}>
          <Toast.Header>
            <img
              src="holder.js/20x20?text=%20"
              className="rounded mr-2"
              alt=""
            />
            <strong className="mr-auto">Notification</strong>
            <small>5 mins ago</small>
          </Toast.Header>
          <Toast.Body>There are some new updates that you might love!</Toast.Body>
        </Toast>
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <Button onClick={() => setShow(true)}>Show Toast</Button>
      </header>
    </div>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

Now create a new file in src directory firebase.js and copy below code

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


const firebaseConfig = {
    apiKey: API_KEY,
    authDomain: AUTH_DOMAIN,
    projectId: PROJECT_ID,
    storageBucket: STORAGE_BUCKET,
    messagingSenderId: MESSAGING_SENDER_ID,
    appId: APP_ID,
    measurementId: MEASUREMENT_ID
};

const firebaseApp = initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
Enter fullscreen mode Exit fullscreen mode

Import firebase.js in your App.js

next create a new file in public directory called firebase-messaging-sw.js and keep it empty for now

npm run start

This is how your screen will look like

Landing screen

Now its time to generate token

go to firebase.js and create new function which will request a permission from a user

const messaging = getMessaging(firebaseApp);


export const getTokens = async (setTokenFound) => {
//VAPID_KEY is the Web push certificates key pair
    return getToken(messaging, {vapidKey: VAPID_KEY }).then((currentToken) => {
        if (currentToken) {
            console.log('current token for client: ', currentToken);
            setTokenFound(true);
            // Track the token -> client mapping, by sending to backend server
            // show on the UI that permission is secured
        } else {
            console.log('No registration token available. Request permission to generate one.');
            setTokenFound(false);
            // shows on the UI that permission is required 
        }
    }).catch((err) => {
    console.log('An error occurred while retrieving token. ', err);
    // catch error while creating client token
});
}
Enter fullscreen mode Exit fullscreen mode

For VAPID_KEY we already have a key if you remember we generated key above from firebase console use that key here

Now back to App.js and add the below code

import {getTokens} from './firebase'

// Inside a App function Just to be sure 😅
const [isTokenFound, setTokenFound] = useState(false);
getTokens(setTokenFound);
Enter fullscreen mode Exit fullscreen mode

Now open you devtool and check console you will have token if not there are might be error saying Permission denied.

Ok this is the part is bit interesting you can manually unable the notification allow from i button before URL

Allow Notification Permission

But the interesting part is you can change your localhost:3000 to 127.0.0.1:3000 and it will ask you for a permission on chrome but both will work on firefox

Permission Request from Browser

Perfect All seems working till this point and you might have a token as well but now we want to see the notification from the server

go to firebase-messaging-sw.js and copy below code

// Scripts for firebase and firebase messaging
importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing the generated config
const firebaseConfig = {
    apiKey: API_KEY,
    authDomain: AUTH_DOMAIN,
    projectId: PROJECT_ID,
    storageBucket: STORAGE_BUCKET,
    messagingSenderId: MESSAGING_SENDER_ID,
    appId: APP_ID,
    measurementId: MEASUREMENT_ID
};

firebase.initializeApp(firebaseConfig);

// Retrieve firebase messaging
const messaging = firebase.messaging();

messaging.onBackgroundMessage(function(payload) {
  console.log('Received background message ', payload);
 // Customize notification here
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
  };

  self.registration.showNotification(notificationTitle,
    notificationOptions);
});
Enter fullscreen mode Exit fullscreen mode

Now go to src->firebase.js and paste a listener function

export const onMessageListener = () =>
  new Promise((resolve) => {
    onMessage(messaging, (payload) => {
      console.log("payload", payload)
      resolve(payload);
    });
  });
Enter fullscreen mode Exit fullscreen mode

back to App.js and add use the newly created listener

import {getTokens, onMessageListener} from './firebase'

// Inside APP function
onMessageListener().then(payload=>{
  console.log(payload)
  setShow(true)
}).catch(err=>console.log(err))
Enter fullscreen mode Exit fullscreen mode

All good Awesome we are ready to receive our first message

Go to firebase console and inside engage->cloud messaging->send your first message

Firebase Cloud Messaging First message screen

Add the requred details only and click on Send Test Message it will show a modal with asking for FCM Registration Token Like this

Asking FCM Token

Here you add the token from your web console that we just generated before. This is your device token which firebase server will understand which device to send a notification And viola You will receive a notification.

Note- Notification will not show the same text as we have entered in firebase since we have configured the static text for demo purpose.

This is the front end part for the backend part i will create part 2 post which will cover server side notifications using firebase-admin and also subscriptions

Hope it was useful.

Top comments (2)

Collapse
 
ntduycs profile image
Duy Nguyen Thanh

Thanks for your sharing

Collapse
 
ishanjirety profile image
Ishan jirety

Deep explanation, Amazing !