Close Menu
Metacognitive

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    Why Self-Awareness Is a Core Pillar in Modern Drug Rehabilitation Clinics?

    May 2, 2025

    The Role Of Javascript In Enhancing The Online Shopping Experience For NFL Jerseys

    February 25, 2025

    Proven Tips To Create Customer Loyalty While Launching Your New Business

    January 27, 2025
    Facebook X (Twitter) Instagram
    Metacognitive
    • Summary
    • Programming
    • JavaScript
    • Productivity
    • Thoughts
    Facebook X (Twitter) Instagram
    Metacognitive
    Home»Metacognitive»Implementing push notifications with Firebase for Javascript apps
    Metacognitive

    Implementing push notifications with Firebase for Javascript apps

    By Jonathan ReynoldsJanuary 21, 20229 Mins Read
    Facebook Twitter Pinterest LinkedIn Tumblr Email
    Share
    Facebook Twitter LinkedIn Pinterest Email

    A tutorial on implementing Firebase web push notifications for React, Next.js, Node.js, Javascript apps.

    These notifications we’re used to on smartphones are available in browser environments too. If you know why are you here exactly, skip this part and jump directly to the solution.

    And these notifications on the web that we hate because every spam site asks our permissions about sending us their spam. However, the technology itself is useful. I didn’t implement web push notifications before. There was no such case, but recently I needed to notify my users about important information as soon as possible. Email is good, but a user should open an email client first. With notifications, you see the popup immediately.

    I decided to write this article because I didn’t find comprehensive information about implementing browser notifications for React, Next.JS, Node apps. We’ll be using Firebase for this purpose, to save time ourselves by not building solutions from scratch.

    Overview of browser push notifications

    So as we said, it’s like those mobile notifications but used in browsers mostly for spamming. It’s worth noting, that you need to send them to a user if that’s really what he subscribed to. Examples:

    • new comments under the user’s post;
    • new message on some platform;
    • important information that should be handled fast;

    The other non-important things may go to email.

    How does it work

    First, you ask a user permission to show the notifications. If you get an acceptance, your website installs a service worker that’ll be handling the notifications. You also send the request to register this particular user in a messaging server, you’ll be asking it to send a notification to someone.

    Push notifications overview

    When a messaging server registers your users, it’ll send you a unique for your user token that you’ll be using as an addressee to send push notifications programmatically.

    You save the registration token from a messaging server. When you want to send a notification, you’ll point out this token for the user you want to send a message to, thus the messaging server understands to whom to send the notification. When a user agrees to receive notifications, your website installs a service worker, it’s a background script that’ll be running on the user’s browser. It’s programmed to handle the messages from the messaging server. When it receives one, it’ll assemble a notification to show to this user.

    Messaging server? This is any server that knows how to communicate with your service worker. You can build it by yourself and code a service worker that will be managing messages from there. But we won’t complicate our life and we’ll be using Firebase.

    Firebase push notifications

    If we use Firebase, we don’t care about the proper messaging server setup because we got covered. What we need is to code logic to ask for the notifications permissions, install a service worker and write a logic to send notifications from our app.

    For further setup, you should create a project in the Firebase Console, and have config from there(a JSON file).

    Front-end set up

    I have a Next.js app, but this algorithm covers any app written in Javascript, it’s a library- and framework-independent.

    Install Firebase to your project so we can leverage simple functions rather than doing requests to FCM(Firebase Cloud Messaging) manually.

    $ npm install firebase
    # or
    $ yarn add firebase

    Find a place where do you want to ask a user about the notification permission. For example, it can be a button that says “Subscribe to browser notifications”. On this button click, you’ll be calling a function getFCMToken() written below:

    import { initializeApp } from 'firebase/app';
    import { getMessaging, getToken } from 'firebase/messaging';
    
    // Replace these values with your project's ones
    // (you can find such code in the Console)
    const firebaseConfig = {
        apiKey: 'xxxxx-xxx',
        authDomain: 'xxxx.firebaseapp.com',
        projectId: 'xxxx-xxxx',
        storageBucket: 'xxxx.appspot.com',
        messagingSenderId: '00000000',
        appId: '0:00000:00000000'
    };
    
    export const app = initializeApp(firebaseConfig);
    const messaging = getMessaging();
    
    export async function getFCMToken() {
        try {
            // Don't forget to paste your VAPID key here
    		// (you can find it in the Console too)
            const token = await getToken(messaging, { vapidKey: <YOUR_VAPID_KEY> });
            return token;
        } catch (e) {
            console.log('getFCMToken error', e);
            return undefined
        }
    }

    With this code, we initialize the Firebase library and write this getFCMToken() function. It retrieves a registration token from FCM, and it also asks a user for notification permission. If the permissions are accepted, only then it’ll communicate with FCM to register this user. Otherwise, the code throws an error, which you catch in the catch block.

    Then, you get an FCM token(a user’s unique token in the FCM system), which you’ll be using to send notifications. So you need to store it somewhere. Usually, you have a server where you may send the token and it’ll save it in the database for this particular user. Otherwise, you won’t be able to send notifications to users. It’s required to have the Firebase Admin SDK, which is available on server environments.

    There are some exceptions though. In some cases when you want only to subscribe users to your notifications like in a newsletter, you may not store the FCM tokens. Firebase has them and you can send the notifications manually from the Console. But it’s not possible to send them automatically(programmatically) because you can’t differentiate users(you don’t have the tokens).

    And the last thing is to have a service worker that will handle the notifications from FCM. Create a file that’ll be available on the root of your web app, the file named firebase-messaging-sw.js. It should be accessible on https://yourwebsite.com/firebase-messaging-sw.js. Its contents:

    // It's a static script file, so it won't be covered by a module bundling system
    // hence, it uses "importScripts" function to load the other libs
    importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js');
    importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js');
    
    // Replace the values with yours
    const firebaseConfig = {
        apiKey: 'xxx',
        authDomain: 'xxx',
        projectId: 'xxx',
        storageBucket: 'xxx',
        messagingSenderId: 'xxx',
        appId: 'xxx'
    };
    
    firebase.initializeApp(firebaseConfig);
    
    const messaging = firebase.messaging();
    
    // Not necessary, but if you want to handle clicks on notifications
    self.addEventListener('notificationclick', (event) => {
        event.notification.close()
    
        const pathname = event.notification?.data?.FCM_MSG?.notification?.data?.link
        if (!pathname) return
        const url = new URL(pathname, self.location.origin).href
    
        event.waitUntil(
            self.clients
                .matchAll({ type: 'window', includeUncontrolled: true })
                .then((clientsArr) => {
                    const hadWindowToFocus = clientsArr.some((windowClient) =>
                        windowClient.url === url ? (windowClient.focus(), true) : false
                    )
    
                    if (!hadWindowToFocus)
                        self.clients
                            .openWindow(url)
                            .then((windowClient) =>
                                windowClient ? windowClient.focus() : null
                            )
                })
        )
    })

    Firebase messaging service worker

    That’s all on the front-end side! You can test your button, on the press, it should ask your permission(a browser asks, to be precise) to send you notifications. When you allow it, you should see an FCM token(console.log it somewhere)

    Sending notifications from the server

    In my case, it’s a Node.js server and we’ll be installing the SDK for it, but the general principle is the same for other languages/platforms.

    $ npm install firebase-admin

    You also have a configuration for the backend in the Console. It differs from the client-side one because it has a private key that you need to sign your notification, which will be sent to FCM. Put this firebase.json file(it’s called service account) somewhere to be accessible from code, you may put it as an environment variable.

    Then you should initialize the Firebase library on a server start(or later if you want to control the flow). I’ve put this logic into a separate file:

    import admin from 'firebase-admin';
    
    import serviceAccount from './config/firebase.json';
    
    export function init() {
        admin.initializeApp({
            credential: admin.credential.cert(serviceAccount),
        });
    }

    On a server start, call init() and Firebase is ready to serve you.

    I won’t cover storing the FCM tokens, I’m sure you know how to do it and it’s not the purpose of this article. So, given you have an initialized Firebase on the server(from the last paragraph) and you have a user’s FCM token, you’re ready to send push notifications to a user’s browser! It looks like this:

    import { getMessaging } from 'firebase-admin/messaging';
    
    // I use Typescript, you may not, but types will help you
    // to understand what data structures FCM expects.
    // It's an internal structure though, firebase-admin has
    // good typings in the library
    interface Message {
    	title: string;
        body: string;
        requireInteraction?: boolean;
        link?: string;
    }
    
    // Use this function to send push notifications to a specific user
    export async function sendFCMMessage(fcmToken: string, msg: Message): Promise<string> {
        try {
            const res = await getMessaging().send({
                webpush: {
                    notification: {
                        ...msg,
                        icon: 'https://your-website.com/favicon.png',
                        requireInteraction: msg.requireInteraction ?? false,
                        actions: [{
                            title: 'Open',
                            action: 'open',
                        }],
                        data: {
                            link: msg.link,
                        },
                    },
                },
                token: fcmToken,
            });
            return res;
        } catch (e) {
            console.error('sendFCMMessage error', e);
        }
    }

    Now, some details on the notification payload. Firebase supports various platforms, here I use the webpush field for my payload. FCM supports other fields:

    interface BaseMessage {
        data?: {
            [key: string]: string;
        };
        notification?: Notification;
        android?: AndroidConfig;
        webpush?: WebpushConfig;
        apns?: ApnsConfig;
        fcmOptions?: FcmOptions;
    }

    I’ve tried to use notification as a general-purpose one, but I had issues with clicking on notifications, a browser didn’t handle clicks(the service worker had the click handler). Plus, there were problems with showing icons on notifications. It’s better to use webpush if you target desktop users. An FCM token can be for various platforms: Android, iOS, web.

    Inside webpush, there are title and body that correspond to a notification’s title and body. There’s icon if you want your notification to have an icon. Put a publicly accessible image you want to be shown. Set requireInteraction to true if you don’t want the notification to be closed after a few seconds, it should wait for the user’s explicit reaction.
    There’s a custom link field inside data, it’s aimed for the service worker to be read and handle the click on notifications correctly.

    I don’t know about all browsers, but my browser(Brave) doesn’t handle the default notification click on the whole area, there should be custom buttons. I define them in the actions field. It seems it doesn’t matter what buttons with actions I put, the “Open” button(action) will open the URL from data.link property I send.

    Summary

    Web push notifications aren’t difficult to implement if you can use Firebase. Also, it’s easy to send messages to various devices on different platforms. Only obtain an FCM token client-side(on a mobile, web, or desktop), and send notifications from a server.

    Jonathan Reynolds

    Jonathan Reynolds is a seasoned mining industry expert with over 15 years of experience in mineral exploration, project management, and strategic development. As a lead content strategist at Kingsrose Mining, he shares insights on sustainable mining practices, investment opportunities, and the future of the industry. Jonathan holds a Master’s degree in Geology from the University of Colorado and has worked on mining projects across North America, Europe, and Asia.

    Javascript
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Jonathan Reynolds
    • Website

    Jonathan Reynolds is a seasoned mining industry expert with over 15 years of experience in mineral exploration, project management, and strategic development. As a lead content strategist at Kingsrose Mining, he shares insights on sustainable mining practices, investment opportunities, and the future of the industry. Jonathan holds a Master’s degree in Geology from the University of Colorado and has worked on mining projects across North America, Europe, and Asia.

    Related Posts

    Why Self-Awareness Is a Core Pillar in Modern Drug Rehabilitation Clinics?

    May 2, 2025

    AI sets new limits for humanity

    May 3, 2023

    How to create a story game with Javascript

    October 27, 2022
    Leave A Reply Cancel Reply

    Recent Posts

    • Why Self-Awareness Is a Core Pillar in Modern Drug Rehabilitation Clinics?
    • The Role Of Javascript In Enhancing The Online Shopping Experience For NFL Jerseys
    • Proven Tips To Create Customer Loyalty While Launching Your New Business
    • AI sets new limits for humanity
    • How to create a story game with Javascript

    Recent Comments

    No comments to show.

    Archives

    • May 2025
    • February 2025
    • January 2025
    • May 2023
    • October 2022
    • September 2022
    • May 2022
    • March 2022
    • January 2022
    • November 2021
    • September 2021
    • August 2021
    • June 2021
    • March 2021
    • October 2020
    • January 2020

    Categories

    • Business
    • Lifestyle
    • Metacognitive
    Facebook X (Twitter) Instagram Pinterest
    © 2025 Copyright Reserved Metacognitive.

    Type above and press Enter to search. Press Esc to cancel.