---
"@context": https://schema.org
"@type": TechArticle
"@id": https://www.twilio.com/docs/chat/javascript/push-notifications-web#article
headline: Push Notifications on Web for Programmable Chat
description: "Add Firebase Cloud Messaging (FCM) push notifications to your JavaScript Programmable Chat web app: configure Firebase, upload keys, and register tokens."
url: https://www.twilio.com/docs/chat/javascript/push-notifications-web
inLanguage: en
dateModified: 2026-06-25T22:35:25.000Z
author:
  "@type": Organization
  name: Twilio Developer Education Team
publisher:
  "@type": Organization
  name: Twilio
---

# Push Notifications on Web for Programmable Chat

> \[!CAUTION]
>
> Programmable Chat has been deprecated and receives no support. Twilio has turned its focus to the next generation of chat: [Twilio Conversations][]. Find out more about the [EOL process][].
>
> * To start a project, see [Conversations][].
> * To switch from Programmable Chat, see the [Migration Guide][] to learn about how to switch.

[Twilio Conversations]: /docs/conversations

[EOL process]: https://www.twilio.com/en-us/changelog/programmable-chat-end-of-life-notice

[Conversations]: /docs/conversations-classic

[Migration Guide]: /docs/conversations-classic/migrating-chat-conversations

The JavaScript Programmable Chat SDK can integrate Firebase Cloud Messaging (FCM) for push notifications. All examples follow Firebase v9 or later.

## Prerequisites

You must manage your push credentials. To send any notifications through FCM, the Conversations (classic) SDK requires your registration token. Let's go through the process of managing your push credentials.

1. [Turn on push notifications][tw-push-config] for your Service instance.
2. Complete the [Add Firebase to your JavaScript project][fb-web-app] guide through the [Firebase Console][].
3. The **Add Firebase SDK** step in the **Add Firebase to your web app** page includes the needed code for Firebase integration. Click the **Copy** button for that code and paste it into a text document for later use.
4. Go to the **Cloud Messaging** settings in your Firebase Project.
5. Scroll to **Web configuration**.
6. Press **Generate key pair**.
7. Copy the displayed public key and paste it into a text document for later use. This key is also known as the *Voluntary Application Server Identification for Web Push* ([VAPID][]) [key][fb-vapid].

## Add your FCM API Key as a Twilio Credential

1. Create a [Credential resource][] in the Twilio Console.
   1. Type the human-readable name for this credential in the **Friendly Name** box.
   2. Choose **FCM Push Credentials** from the **Type** dropdown menu.
      To generate a credential SID using your API key, see [the **Credentials** page in the legacy console][tw-credentials] page.
2. Click **Create**.

## Modify your app code

1. In your terminal, set all of your credentials as environment variables. This follows security best practices.
   ```bash
   export TWILIO_ACCOUNT_SID="{my_account_sid}"
   export TWILIO_API_KEY="{my_api_key}"
   export TWILIO_API_SECRET="{my_api_secret}"
   export TWILIO_CONVERSATIONS_SERVICE_SID="{my_conversations_service_sid}"
   export TWILIO_FCM_CREDENTIAL_SID="{my_fcm_credential_sid}"
   export FIREBASE_API_KEY="{my_firebase_api_key}"
   export FIREBASE_AUTH_DOMAIN="{my_firebase_auth_domain}"
   export FIREBASE_PROJECT_ID="{my_firebase_project_id}"
   export FIREBASE_STORAGE_BUCKET="{my_firebase_storage_bucket}"
   export FIREBASE_MESSAGING_SENDER_ID="{my_firebase_messaging_sender_id}"
   export FIREBASE_APP_ID="{my_firebase_app_id}"
   export FIREBASE_VAPID="{my_firebase_vapid}"
   ```
2. Open your app code file.
3. In your app code, declare and import your functions.
   ```js
   // Import the necessary functions from the modern Firebase SDKs
   import { initializeApp } from "firebase/app";
   import { getMessaging, getToken, onMessage } from "firebase/messaging";
   import twilio from "twilio";
   ```
4. Add your credentials.
   ```js
   // Twilio Configuration Variables
   const accountSid = process.env.TWILIO_ACCOUNT_SID;
   const apiKey = process.env.TWILIO_API_KEY;
   const apiSecret = process.env.TWILIO_API_SECRET;
   const conversationServiceSid = process.env.TWILIO_CONVERSATIONS_SERVICE_SID;
   const fcmCredentialSid = process.env.TWILIO_FCM_CREDENTIAL_SID; 
   // Firebase Configuration Variables
   const firebaseApiKey = process.env.FIREBASE_API_KEY;
   const firebaseAuthDomain = process.env.FIREBASE_AUTH_DOMAIN;
   const firebaseProjectId = process.env.FIREBASE_PROJECT_ID;
   const firebaseStorageBucket = process.env.FIREBASE_STORAGE_BUCKET;
   const firebaseMessagingSenderId = process.env.FIREBASE_MESSAGING_SENDER_ID;
   const firebaseAppId = process.env.FIREBASE_APP_ID;
   const firebaseVapid = process.env.FIREBASE_VAPID;
   ```
5. Initialize your Firebase Configuration.
   ```js
   // Firebase Configuration
   const firebaseConfig = {
    apiKey: firebaseApiKey,
    authDomain: firebaseAuthDomain,
    projectId: firebaseProjectId,
    storageBucket: firebaseStorageBucket,
    messagingSenderId: firebaseMessagingSenderId,
    appId: firebaseAppId
   };
   ```
6. Initialize your Twilio chat grant.
   ```js
   const AccessToken = twilio.jwt.AccessToken;
   const ChatGrant = AccessToken.ChatGrant;

   const chatGrant = new ChatGrant({ 
     serviceSid: conversationServiceSid, 
     // Passing the environment variable string directly per SDK requirements
     pushCredentialSid: fcmCredentialSid 
   });
   ```
7. Initialize Firebase in your web app
   ```js
   const app = firebaseAppModule.initializeApp(firebaseConfig);
   const messaging = firebaseMessagingModule.getMessaging(app);
    
   console.log("✅ Firebase libraries verified and initialized successfully.");
   ```
8. Request push permissions from the end user and get your FCM token.
   ```js
   async function initializeAppWithPush() {
     try {
       console.log("Checking and importing Firebase libraries...");
       
       // Dynamically attempt to load the modules to verify they exist
       const firebaseAppModule = await import("firebase/app");
       const firebaseMessagingModule = await import("firebase/messaging");

       // Guard Clause: Verify necessary initialization functions are present
       if (typeof firebaseAppModule.initializeApp !== "function" || 
           typeof firebaseMessagingModule.getMessaging !== "function") {
         throw new Error("Required Firebase initialization functions are missing from the loaded modules.");
       }

       // Initialize Firebase Core and Messaging
       const app = firebaseAppModule.initializeApp(firebaseConfig);
       const messaging = firebaseMessagingModule.getMessaging(app);
       
       console.log("✅ Firebase libraries verified and initialized successfully.");

       // --- PERMISSION AND TOKEN MANAGEMENT ---
       
       // Request permission using native browser API
       const permission = await Notification.requestPermission();
       
       if (permission !== 'granted') {
         throw new Error("Notification permission was denied by the user.");
       }
       
       console.log("Notification permission granted.");

       // Retrieve FCM Token using modern modular function pattern
       // Note: process.env.FIREBASE_VAPID_KEY is recommended for modern web pushes
       const fcmToken = await firebaseMessagingModule.getToken(messaging, { 
         vapidKey: process.env.FIREBASE_VAPID_KEY 
       });

       console.log("FCM Token retrieved successfully.");

       // --- CONTINUING WITH STEP 7: TWILIO INTEGRATION ---
       
       // Passing FCM token to the conversationClientInstance to register for push notifications
       conversationClientInstance.setPushRegistrationId('fcm', fcmToken);

       // Registering event listener on new message from Firebase to pass to Twilio Conversations SDK
       firebaseMessagingModule.onMessage(messaging, (payload) => {
           conversationClientInstance.handlePushNotification(payload);
       });

       console.log("✅ Push registration and event listeners successfully attached.");

     } catch (err) {
       // Gracefully handles missing libraries, denied permissions, or missing tokens in one block
       console.error("❌ CRITICAL ERROR: Application execution halted.");
       console.error(`Details: ${err.message}`);
       
       // Stop further processing completely
       return;
     }
   }
   ```
9. Add the function call to run the script.
   ```js
   // Run the script
   initializeAppWithPush();
   ```

> \[!NOTE]
>
> Register service workers for multiple Chat channels in different tabs.
> When a Chat tab sits in the background, you need to run the service worker.
> This allows FCM to send push notifications.

Next: [Webhook Events][]

[Webhook Events]: /docs/chat/webhook-events

[Credential resource]: /docs/verify/quickstarts#push

[Firebase Console]: https://console.firebase.google.com

[tw-credentials]: https://www.twilio.com/console/notify/credentials/create

[tw-push-config]: /docs/chat/push-notification-configuration

[fb-web-app]: https://firebase.google.com/docs/web/setup

[fb-vapid]: https://developer.chrome.com/blog/web-push-interop-wins#introducing_vapid_for_server_identification

[vapid]: https://datatracker.ietf.org/doc/html/draft-thomson-webpush-vapid
