Utilizing Firebase Cloud Messaging for push notifications in Twilio Conversations

I am currently facing a challenge in setting up push notifications using Twilio Conversations and Firebase Cloud Messaging on a Next.js 12 app. The documentation assumes the use of Firebase 8 syntax, but I am working with Firebase 9 in this case. I have been encountering difficulties in getting push notifications to display while the page is open. Even though I have set up the service worker as per Firebase docs, it does not seem to recognize when a new message is received from Twilio to show the notification.

Here are the docs I have followed:

What I've attempted

On the backend, I include the Push Credential SID when constructing a new ChatGrant:

const chatGrant = new ChatGrant({
  pushCredentialSid: process.env.TWILIO_PUSH_CREDENTIAL_SID,
  serviceSid: CONVERSATIONS_SID
});

In the frontend, I followed the Twilio documentation for Firebase setup:

init.ts

import { getMessaging, getToken, onMessage } from "firebase/messaging";
import { initializeApp } from "firebase/app";
import { Client } from "@twilio/conversations";

// Code omitted
const firebaseConfig = {};

export function getPermission(client: Client) {
  const app = initializeApp(firebaseConfig);
  const messaging = getMessaging(app);
  getToken(messaging, { vapidKey:"KEY" })
    .then((data) => {
      console.log({ data });
      client.setPushRegistrationId("fcm", data).catch((error) => {
        console.error({ error });
      });
      onMessage(messaging, (payload) => {
        console.log({ payload });
        client.handlePushNotification(payload).catch((error) => {
          console.error(error);
          // test
        });
      });
    })
    .catch((error) => {
      console.error(error);
      // test
    });
}

I invoke getPermission from this file once the conversation app loads.

  // chatClient is stored in a ref so it doesn't recalculate/refetch/reauthorize all the time
  const chatClient = useRef(null);
  // [Other code]
  chatClient.current = new ConversationClient(data.chatAccessToken);
  chatClient.current.on("connectionStateChanged", async (state) => {
    switch (state) {
      case "connected": {
        // Only get permission once the chat client is fully set up
        getPermission(chatClient.current);
        // ..........

Regarding my service worker firebase-messaging-sw.js:

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

if (!firebase.apps.length) {
  firebase.initializeApp({
    // CONFIG GOES HERE
  });
}

const messaging = firebase.messaging();

//background notifications will be received here
messaging.onBackgroundMessage(function(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: '/android-chrome-192x192.png'
  };

  self.registration.showNotification(notificationTitle, notificationOptions);
});

Current Situation

  • The messaging.onBackgroundMessage event in the service worker does not appear to be triggered. I am unsure of the root cause - whether Twilio is failing to pass message information to Firebase or if Firebase is not properly listening when Twilio sends the data. Could there have been changes from version 8 to 9 that are affecting this?
  • In init.ts, the onMessage method is also not being invoked. Similarly, I am uncertain if Twilio is sending the correct information to Firebase or if I missed configuring something.

No console errors or warnings are displayed, and the network tab doesn't provide much insight either.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to retrieve the value of a concealed element without any activation signal

In my project, I've created a slider that dynamically shows different forms one by one. Each form contains a hidden element with a specific value that I need to retrieve (using its class) every time a new form is displayed. This way, I can use that el ...

Insufficient Resources Error (net::ERR_INSUFFICIENT_RESOURCES) encountered while executing jQuery script with multiple ajax requests for 2 minutes

Upon initially loading the code below, everything seems to be functioning smoothly with the dayofweek and hourofday functions. However, shortly thereafter, the browser (Chrome) freezes up and displays the error message: net::ERR_INSUFFICIENT_RESOURCES. Thi ...

Top scenario and illustration of utilizing clusters in nodejs

I've been exploring the concept of clusters and I'm still a bit unclear about the most effective use-case scenario for them. Can anyone provide an example to help clarify this for me? ...

Having trouble applying global styles in _app.js in NextJS?

After embarking on a new project, I diligently followed the guidelines outlined in this page from NextJS documentation: https://nextjs.org/docs/basic-features/built-in-css-support I meticulously copied every step provided under the section titled "Adding ...

When trying to manually trigger the firing of the autocomplete function to get a place using Google API

My goal is to retrieve the data from autocomplete.getPlace() when triggering this event manually. Essentially, I have a function that captures the user's location in Lat/Lng format, and afterward, I aim to access other useful data using getPlace() su ...

Displaying both items upon clicking

Hey there, I'm having an issue where clicking on one article link opens both! <span class='pres'><img src='http://files.appcheck.se/icons/minecraft.png' /></span><span class='info'><a href=&apo ...

While attempting to use $scope.$apply() in Angular, I encountered a bug that

I have set up a specific example in a jsbin: http://jsbin.com/deqerelita/1/ Situation The concept is quite straightforward. You click a button, the controller adds to the model, and the view updates accordingly with a hidden input type="file". After the v ...

Ways to obtain a tab and designate it as the default in angular when using angular material Tabs

I am facing an issue with accessing tabs within a nested component. The parent component contains the tab feature and to reach the tabs inside the child component, I am using the following code: document.querySelectorAll('.mat-tab-group'); The a ...

Select an item, then toggle classes on the other items to add or remove them

My code includes the following HTML elements: <ul> <li class="one"><a href="#">one</a></li> <li class="two"><a href="#">two</a></li> <li class="three"><a href="#">three</a>&l ...

Discovering country code details through the Geonames service API rather than relying on the HTML5 location object

My goal is to retrieve the country code of the user's current location using the Geonames Service API. However, it seems that the API only provides a two-letter country code instead of a three-letter one, which is what I require. To work around this i ...

Supporting wildcard redirect URLs for Vercel in Asp .Net Identity Server

Currently, I am working with Duende IdentityServer for my back-end RestApi and using Vercel to test the front-end. However, I am facing an issue where I cannot login to IdentityServer with Vercel due to the redirectUrl not being allowed. I have come acros ...

What is the best approach for establishing an asynchronous connection to a MongoDB database?

Managing a MongoDB database using JavaScript and Node.js with Mongoose, I needed to retrieve an array containing the names of all collections in the database. Taking this into consideration, I implemented the following code snippet. let connection = mongoo ...

Angular UI Grid failing to properly display date formatting

Currently, I am using Angular's UI Grid to showcase multiple columns. However, I am facing an issue with formatting the date column. The date is being displayed as /Date(1451346632162-0000)/, and similar formats. I have attempted to apply filters in ...

Unable to display Bootstrap 5 modal

I am currently in the process of constructing a basic webpage that includes a navigation bar and a table. The table rows are being dynamically generated through a simple JavaScript script that fetches data asynchronously from a database. I opted to utilize ...

Adjust the JSON format that is retrieved from an Ajax call

I am working with a JQuery plugin that includes the following code snippet: transformResult: function(response, originalQuery) { } Within this function, I have the task of converting Json data from the originalQuery to the response format: [ { "Id": ...

Issue with the dynamic updating of props

Every time a radio button is clicked within Test.js, the handleclick function executes, updating an array. However, the issue lies in not sending this updated array back to graph_test.js. As a result, graph_test.js only receives the initial array filled wi ...

Error message: Unable to locate Bootstrap call in standalone Angular project after executing 'ng add @angular/pwa' command

Having an issue while trying to integrate @angular/pwa, it keeps showing me an error saying "Bootstrap call not found". It's worth mentioning that I have removed app.module.ts and am using standalone components in various places without any module. Cu ...

How can I retrieve elements i from each array in HandlebarsJS and then access element j, and so on?

Given a JSON like this: { "network": [ { "name": [ "John", "Jill", "June" ] }, { "town": [ "London", "Paris", "Tokyo" ] }, { "age" : [ "35", "24", "14" ] } ] } Unfortunately, my data is in this format and I have to work w ...

The phantom stdout for Node 4.2.0 is showing an error with code NETWORK_ERR: XMLHttpRequest Exception 101. This error indicates that a network error

Executing the code below in node 4.2.0, it is triggered within a scheduled node cron job rather than through the terminal. The website being 'requested' is . module.exports.dynamicRequest = function(url, callback) { var makeDynamicRequest = fu ...

Encounter issue when attempting to insert multiple items into MongoDB

// Import User and Item Models const User = require('../../models/User'); const Item = require('../../models/Item'); router .post('/login/:id', passport.authenticate('jwt', {session: false}), (req, res) => { ...