2

I'm using Twilio programmable chat and wanted to send push notification to mobile app(iOS, Android) and web app as well. I followed the steps given in Twilio Still, I'm not getting notifications in web and mobile apps as well. Following is the code I implemented.

<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.3.0/firebase-messaging.js"></script>
<script src="firebase-messaging-sw.js"></script>
<script>
  // Initialize Firebase
  var config = {
    apiKey: "******************",
    authDomain: "*****.firebaseapp.com",
    databaseURL: "https://******.firebaseio.com",
    projectId: "******",
    storageBucket: "******.appspot.com",
    messagingSenderId: "***************"
  };
  firebase.initializeApp(config);   
</script>

During user login I'm doing the following

/* Generating token for Twilio chat */
                $scope.URL = Path + "/twilio/chat/generateToken";
                var data = {"identity":localStorage.userId,"deviceId":guid(),"pushCredentialSid":"**********"}
                RestAPIService.post($http,data,$scope,$scope.URL, function ( responsesData ) {
                    if(responsesData.data.status == "success"){
                        var twilioToken = responsesData.data.token;
                        Twilio.Chat.Client.create(twilioToken).then(function(twilioClient) {
                            twilioChatClient = twilioClient;

                            // Twilio notification 
                            firebase.initializeApp(config);
                            if (firebase && firebase.messaging()) {
                              // requesting permission to use push notifications
                              firebase.messaging().requestPermission().then(function() {
                                console.log ("Notification permission granted.");
                                // getting FCM token
                                firebase.messaging().getToken().then(function(fcmToken) {
                                    console.log ("token is:" + fcmToken);
                                    // continue with Step 7 here 
                                    // passing FCM token to the `chatClientInstance` to register for push notifications
                                    twilioChatClient.setPushRegistrationId('fcm', fcmToken);

                                    // registering event listener on new message from firebase to pass it to the Chat SDK for parsing
                                    /* firebase.messaging().onMessage(function(payload){
                                        twilioChatClient.handlePushNotification(payload);
                                    }); */ 
                                }).catch(function(err) {
                                  // can't get token
                                  console.log(err);
                                });
                              }).catch(function(err){
                                // can't request permission or permission hasn't been granted to the web app by the user
                                console.log(err);
                              });
                            } else {
                                // no Firebase library imported or Firebase library wasn't correctly initialized
                            }
                            /* Twilio notification */
                        });

                    }       
                });

I'm not sure, how to proceed further, and didnt know whether I missed anything. If someone one who has implemented push notification from web app to mobile apps please guide me to proceed further.

Sankar
  • 343
  • 2
  • 6
  • 18

1 Answers1

0

Twilio's documentation regarding this really expects you to know about Firebase because their documentation is fairly lacking on the topic when it's normally great for everything else Twilio. I ran into issues myself because I was using a blank service worker but the documentation clearly tells us what to do. To get both foreground and background notifications working, in the service worker, it's exactly like the example on https://firebase.google.com/docs/cloud-messaging/js/receive. After configuring firebase in the service worker, at a minimum all you need is 'const messaging = firebase.messaging()' to get foreground notifications working. For background notifications, you can follow Google's example to use messaging.setBackgroundMessageHandler() as this is probably best for most use case scenarios. As an alternative, you can just as easily use an event listener for the push event if you want more control of how you'll handle the notification. I.e.,

 

   // This event is where you'll handle background message.  You can still do self.registration.showNotification() here.
    self.addEventListener('push', function (event) {
        if (event.data) {
            console.log(`firebase-messaging-sw (background handler):  This push event has data: ${event.data.text()}`);
            //self.registration.showNotification('Title', { body: 'Background Message body.', icon: '/firebase-logo.png' });
        }
        else {
            console.log('firebase-messaging-sw(background handler):  This push event has no data.');
        }
    });

Btw, since this is a service worker, you do not need to reference this script in your page. It's a service worker, navigator.serviceWorker.register() will ensure it runs in the background of your application.

As for the Twilio piece, you'll need to create the Twilio client with a token (w/ chat grant) for the user who will receive the notifications. Using Twilio's code example but with additional pieces for clarity, this code example should help:

firebase.initializeApp({
  apiKey: 'api-key',
  authDomain: 'project-id.firebaseapp.com',
  databaseURL: 'https://project-id.firebaseio.com',
  projectId: 'project-id',
  storageBucket: 'project-id.appspot.com',
  messagingSenderId: 'sender-id',
  appId: 'app-id',
  measurementId: 'G-measurement-id',
});

const handleNotificationsForUser = function (userId) {
    let getChatClient;
    let accessToken = '';
 
 // I'm getting my token from C# code.  Leaving this here for clarity.
    $.ajax({
        url: `chat/accesstoken/${userId}`,   
        dataType: 'JSON',
        async: false,
        success: function (data) {
            accessToken = data.result;
            console.log(`accestoken: ${accessToken}`);
            getChatClient = new Twilio.Chat.Client.create(accessToken);
        }
    });

    getChatClient.then(function (chatClient) {
        if (firebase && chatClient) {
            if ('serviceWorker' in navigator) {
                navigator.serviceWorker.register('/Scripts/firebase-messaging-sw.js').then(function (registration) {
                    firebase.messaging().useServiceWorker(registration);
                    console.log(`handleNotificationsForUser():  ServiceWorker registration successful with scope:  ${registration.scope}`);
                    if (firebase && firebase.messaging()) {                            
                        firebase.messaging().requestPermission().then(() => {       // requesting permission to use push notifications                            
                            firebase.messaging().getToken().then((fcmToken) => {    // getting FCM token
                                console.log(`fcm: ${fcmToken}`);
                                chatClient.setPushRegistrationId('fcm', fcmToken);

                                // This is where we would handle the foreground.  This registers an event listener 
                                // on new message from firebase for you to do something with it.
                                // The chat window must have focus for messaging().onMessage to work.
                                firebase.messaging().onMessage(function (payload) {
                                    console.log(`init - firebase.handleNotificationsForUser() - (foreground handler):  This push event has data: ${JSON.stringify(payload)}`);
                                    chatClient.handlePushNotification(payload); 
         
         // todo:  your implementatation for UI here
                                });
                            }).catch((err) => {
                                console.log(`handleNotificationsForUser():  Can't get token.  ${err}`);
                            });
                        }).catch((err) => {
                            console.log(`handleNotificationsForUser():  Can't request permission or permission hasn't been granted to the web app by the user.  ${err}`);
                        });
                    } else {
                        console.log("handleNotificationsForUser():  No Firebase library imported or Firebase library wasn't correctly initialized.");
                    }
                }, function (err) {
                    console.log(`handleNotificationsForUser(): ServiceWorker registration failed: ${err}`);
                });
            }
        } else {
            console.log('handleNotificationsForUser():  no firebase.js imported');
        }
    });
} 

I hope this helps anyone who is trying to do this on the web.

Will Sams
  • 196
  • 2
  • 14