Skip to contentSkip to navigationSkip to topbar
Page toolsOn this page
Looking for more inspiration?Visit the

Push Notifications on the Web for Conversations (classic)


(error)

Programmable Chat deprecated

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(link takes you to an external page).

  • To start a project, see Conversations.
  • To switch from Programmable Chat, see the Migration Guide to learn about how to switch.

Push notifications are an important part of the web experience. Users have grown accustomed to push notifications being part of virtually every app that they use. The Twilio Conversations (classic) JavaScript SDK can integrate Firebase Cloud Messaging (FCM) for push notifications. All examples follow Firebase v9 or later.


Prerequisites

prerequisites page anchor

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 for your Service instance.
  2. Complete the Add Firebase to your JavaScript project(link takes you to an external page) guide through the Firebase Console(link takes you to an external page).
  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(link takes you to an external page)) key(link takes you to an external page).

Add your FCM API Key as a Twilio Credential

add-your-fcm-api-key-as-a-twilio-credential page anchor
  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(link takes you to an external page) page.
  2. Click Create.

  1. In your terminal, set all of your credentials as environment variables. This follows security best practices.
    1
    export TWILIO_ACCOUNT_SID="{my_account_sid}"
    2
    export TWILIO_API_KEY="{my_api_key}"
    3
    export TWILIO_API_SECRET="{my_api_secret}"
    4
    export TWILIO_CONVERSATIONS_SERVICE_SID="{my_conversations_service_sid}"
    5
    export TWILIO_FCM_CREDENTIAL_SID="{my_fcm_credential_sid}"
    6
    export FIREBASE_API_KEY="{my_firebase_api_key}"
    7
    export FIREBASE_AUTH_DOMAIN="{my_firebase_auth_domain}"
    8
    export FIREBASE_PROJECT_ID="{my_firebase_project_id}"
    9
    export FIREBASE_STORAGE_BUCKET="{my_firebase_storage_bucket}"
    10
    export FIREBASE_MESSAGING_SENDER_ID="{my_firebase_messaging_sender_id}"
    11
    export FIREBASE_APP_ID="{my_firebase_app_id}"
    12
    export FIREBASE_VAPID="{my_firebase_vapid}"
  2. Open your app code file.
  3. In your app code, declare and import your functions.
    1
    // Import the necessary functions from the modern Firebase SDKs
    2
    import { initializeApp } from "firebase/app";
    3
    import { getMessaging, getToken, onMessage } from "firebase/messaging";
    4
    import twilio from "twilio";
  4. Add your credentials.
    1
    // Twilio Configuration Variables
    2
    const accountSid = process.env.TWILIO_ACCOUNT_SID;
    3
    const apiKey = process.env.TWILIO_API_KEY;
    4
    const apiSecret = process.env.TWILIO_API_SECRET;
    5
    const conversationServiceSid = process.env.TWILIO_CONVERSATIONS_SERVICE_SID;
    6
    const fcmCredentialSid = process.env.TWILIO_FCM_CREDENTIAL_SID;
    7
    // Firebase Configuration Variables
    8
    const firebaseApiKey = process.env.FIREBASE_API_KEY;
    9
    const firebaseAuthDomain = process.env.FIREBASE_AUTH_DOMAIN;
    10
    const firebaseProjectId = process.env.FIREBASE_PROJECT_ID;
    11
    const firebaseStorageBucket = process.env.FIREBASE_STORAGE_BUCKET;
    12
    const firebaseMessagingSenderId = process.env.FIREBASE_MESSAGING_SENDER_ID;
    13
    const firebaseAppId = process.env.FIREBASE_APP_ID;
    14
    const firebaseVapid = process.env.FIREBASE_VAPID;
  5. Initialize your Firebase Configuration.
    1
    // Firebase Configuration
    2
    const firebaseConfig = {
    3
    apiKey: firebaseApiKey,
    4
    authDomain: firebaseAuthDomain,
    5
    projectId: firebaseProjectId,
    6
    storageBucket: firebaseStorageBucket,
    7
    messagingSenderId: firebaseMessagingSenderId,
    8
    appId: firebaseAppId
    9
    };
  6. Initialize your Twilio chat grant.
    1
    const AccessToken = twilio.jwt.AccessToken;
    2
    const ChatGrant = AccessToken.ChatGrant;
    3
    4
    const chatGrant = new ChatGrant({
    5
    serviceSid: conversationServiceSid,
    6
    // Passing the environment variable string directly per SDK requirements
    7
    pushCredentialSid: fcmCredentialSid
    8
    });
  7. Initialize Firebase in your web app
    1
    const app = firebaseAppModule.initializeApp(firebaseConfig);
    2
    const messaging = firebaseMessagingModule.getMessaging(app);
    3
    4
    console.log("✅ Firebase libraries verified and initialized successfully.");
  8. Request push permissions from the end user and get your FCM token.
    1
    async function initializeAppWithPush() {
    2
    try {
    3
    console.log("Checking and importing Firebase libraries...");
    4
    5
    // Dynamically attempt to load the modules to verify they exist
    6
    const firebaseAppModule = await import("firebase/app");
    7
    const firebaseMessagingModule = await import("firebase/messaging");
    8
    9
    // Guard Clause: Verify necessary initialization functions are present
    10
    if (typeof firebaseAppModule.initializeApp !== "function" ||
    11
    typeof firebaseMessagingModule.getMessaging !== "function") {
    12
    throw new Error("Required Firebase initialization functions are missing from the loaded modules.");
    13
    }
    14
    15
    // Initialize Firebase Core and Messaging
    16
    const app = firebaseAppModule.initializeApp(firebaseConfig);
    17
    const messaging = firebaseMessagingModule.getMessaging(app);
    18
    19
    console.log("✅ Firebase libraries verified and initialized successfully.");
    20
    21
    // --- PERMISSION AND TOKEN MANAGEMENT ---
    22
    23
    // Request permission using native browser API
    24
    const permission = await Notification.requestPermission();
    25
    26
    if (permission !== 'granted') {
    27
    throw new Error("Notification permission was denied by the user.");
    28
    }
    29
    30
    console.log("Notification permission granted.");
    31
    32
    // Retrieve FCM Token using modern modular function pattern
    33
    // Note: process.env.FIREBASE_VAPID_KEY is recommended for modern web pushes
    34
    const fcmToken = await firebaseMessagingModule.getToken(messaging, {
    35
    vapidKey: process.env.FIREBASE_VAPID_KEY
    36
    });
    37
    38
    console.log("FCM Token retrieved successfully.");
    39
    40
    // --- CONTINUING WITH STEP 7: TWILIO INTEGRATION ---
    41
    42
    // Passing FCM token to the conversationClientInstance to register for push notifications
    43
    conversationClientInstance.setPushRegistrationId('fcm', fcmToken);
    44
    45
    // Registering event listener on new message from Firebase to pass to Twilio Conversations SDK
    46
    firebaseMessagingModule.onMessage(messaging, (payload) => {
    47
    conversationClientInstance.handlePushNotification(payload);
    48
    });
    49
    50
    console.log("✅ Push registration and event listeners successfully attached.");
    51
    52
    } catch (err) {
    53
    // Gracefully handles missing libraries, denied permissions, or missing tokens in one block
    54
    console.error("❌ CRITICAL ERROR: Application execution halted.");
    55
    console.error(`Details: ${err.message}`);
    56
    57
    // Stop further processing completely
    58
    return;
    59
    }
    60
    }
  9. Add the function call to run the script.
    1
    // Run the script
    2
    initializeAppWithPush();