This tutorial is outdated. We're currently working on an updated version. In the meantime, for instructions on building a chat app using CometChat, please visit our documentation.
In a previous tutorial I wrote about how to build a one-on-one chat using Angular and CometChat. This tutorial picks up where the last one ended and shows how to enable chat push notifications using the CometChat push notifications extension.
If you stumbled upon this tutorial first and wish to follow along from the very beginning - please do by starting here. Otherwise you can download the source code from the previous tutorial (I will show you how in the next sections) and carry on from there.
Introduction
When the application is in the background we will render a browser notification:
And when the application is in the foreground I will show you how to optionally enable in-app notifications using a snackBar:
Setup
To pick up from where we left our application from the previous tutorial, we need to get the repository from the initial commit. We can do that with these commands:
These commands cloned the repository and then we went to a specific commit. Now you can follow along. We can install all the packages and we’re good to go. Inside the project folder run:
Everything is now set up, and we’re able to work on adding push notifications.
Firebase
CometChat is a proponent of the Unix philosophy which is to do one thing and do it really well. Rather than building push notifications infrastructure CometChat instead focuses on chat and then create extensions which connect you with other services. The CometChat push notifications extension enables you to seamlessly connect with Firebase for chat notifications. Rest assured it is completely free.
To enable push notifications for our app, we need to create a new Firebase project and within that a new Web application.
Head to the Firebase console and click on Add project +:
When creating the project, enter a name, continue and uncheck Enable Google Analytics for this project. Then you’ll be able to hit Create Project and you’re done ✨.
Inside the new project you need to add a web application. Below the title of the new project, you have the Add App button. Click on it and then on the Web App option:
Web app option is the third in the list:
Give it a name and hit Register App. On the next step, Add Firebase SDK, copy the firebaseConfig object and paste it in your environment.ts file in the Angular app. It should look something like this:
Keep Firebase open in a tab as we will need to reference some keys but aside from that, everything is set up in the Firebase dashboard so we can move on and enable notifications in CometChat.
CometChat Extension
To use push notifications, we now need to enable them inside CometChat. Go to the Dashboard and Explore your application:
Inside our app, go to extensions and hit Add Extension on Push Notification. To enable this, we need the server key from Firebase.
Go back to Firebase Console, click on the project that you previously created and go to the settings page of the new application:
From there, go to Cloud Messaging tab (the second one) and fetch the project credentials. Use them inside the CometChat Dashboard to enable the Push Notifications extensions.
This is all the required setup that we need, in both CometChat and Firebase to use push notifications. Now we can add them to our project.
AngularFire
The best way to use Firebase inside your Angular project is through AngularFire. This is the official library and can be found under the Angular project on GitHub.
We first need to install it:
Inside our application module, we now need to import the angular fire module and initialize it. Since we’re using the messaging module to show notifications we need to import that one also:
And we need to add both of them to the imports array of the module, passing in the config object that we’ve previously added to our environment file:
Angular Fire is now set up and ready to be used 🙂.
Push notifications
When we receive a new message, our application can be in two states. It can be active, and then we get a notification from Firebase that a new message was received and we can do something about it. More importantly, our application can be minimized, or in the background state, and then we need to use a service worker to handle the message.
A service worker is a script that our browser will run in the background, totally separate from our web page. This script will allow us to handle functionality that doesn’t need any user interaction, for example showing notifications.
The problematic part here is that AngularFire does not work with the default service worker provided by Angular, so we have to roll out our own. The good news is that the library will handle everything for us. As long as we provide a script that will be run as a background worker, everything else is handled.
We start by adding a new file called manifest.json inside our src folder:
We have a name for our application, a start URL and a sender id. The sender id is a global value, so please don’t change this.
We need to add a reference to this file inside our index.html file:
Now we need to add the actual worker script. In the same folder, src, create a new file called firebase-messaging-sw.js. Inside it, we’ll place the functionality to handle notifications when our application is not active.
First, we need to import the Firebase lib:
Then, we need to initialized the lib:
We already have the sender id, it’s the same value as messagingSenderId from our Firebase config object inside our environment file. So you can copy and paste it from there.
The last and most important part is to handle any background messages that we get and show a notification:
Using setBackgroundMessageHandler method from Firebase messaging library we register a function that will be called each time a notification is received. First, we parse the message to get the sender and then we create a new notification with the message and the icon of the sender.
Using the showNotification method we create and display it. For more information have a look at the great MDN documentation.
Both of these files need to be added to the assets array inside the angular config file. This is because we want them deployed to our output folder at each build:
Notifications service
Inside our application we need to do two things. Enable notifications and listen for any incoming messages when the app is active. In order to do this, we’ll create a new notifications service:
To register our app to retrieve notifications, we need to ask the user for permission and get a token from Firebase. Then we need to make a request to the ComeChat API to register this.
Inside the constructor we need to get an instance of the messaging module from AngularFire and of HTTP client from Angular:
AngularFire has a streamlined method to request permission and get the token, all in one step. The requestToken observable. Subscribing to this, will request permissions from the user and fetch a token from Firebase.
Once we have this token, we need to make a post request to CometChat API to register that we want to receive notifications. After this is done, notifications are enabled for our application:
Whenever we get a new token value, we map that value to the URL from CometChat where we need to make the request:
We create a topic name from our application id, type of the channel for which we want to receive a notification (user or group) and the id of the entity. Then we append it, together with the token to the ComeChat address. If you want to read more about managing notifications in ComeChat have a look at the documentation. It explains almost everything you need, including how to set up a new Firebase project and how to make the POST request to the CometChat API.
After we have the URL, we make a post request to it, with the application id as payload:
{% c-line %} this.http.post(url, { appId: environment.appId }){% c-line-end %}
Subscribing to this observable will request permissions from the user, get a token from Firebase and make the request to the API. All in a few lines of code 🙂.
We should also consider what happens when the application has focus. In that case it would be better to render an in-app notification using snackBar. To acomplish this, we can leverage the same AngularFireMessaging and subscribe to the messages observable:
Whenever we get a new notification, we extract the title and message from it and use the Snackbar from Angular Material to show it on the UI. To use the Snackbar we have to import it inside the constructor:
We also have the AuthService here, since we used it in the method where we retrieved the CometChat URL to retrieve the user id.
Our service is up and done, now we have to use it in our application.
Updating our app
To leverage our notifications, we can go to the chat component and enable them. First, we add the newly created service inside the constructor:
readonly notificationsService: NotificationsService
Then, we can create a method to enable the notifications:
We call the method from our service and subscribe to the result. If everything worked, we show a Snackbar to let the user know that notifications were enabled.
Now, inside the init method we enable the notifications and listen for new messages:
All done! Notifications are not enabled for our application and we’ll see them in both cases. When the application is active, we’ll see a Snackbar and when it’s not we see the system notifications.
Conclusion
Using the CometChat SDK, Firebase and the AngularFire library we were able to add notifications to our application with not that much effort. These tools take care of the hard work for us.
Now we’re able to engage users better in our applications while showing them relevant notifications.
Adrian Faciu
CometChat