•8 months ago
In any chat application, one of the most integral features is being able to notify users of new messages. While providing this feature comes with its own set of challenges (listeners, timing, notification types, keeping track of which messages are read, etc.), notifying users of unread messages doesn't have to be challenging.
Among the many ways in which building a chat app/feature becomes infinitely easier when building with Stream Chat is the fact that the capabilities for displaying notifications for various actions are built right into the service; the only thing you need to do is hook it up with the notification system of the platform you’re building for!
In this article, we’ll explore how you can display notifications when a user receives a new message. We’ll talk about how to prompt the user to enable notifications, then show how to listen for events that we can then hook into for notifications.
Here’s a live demo of what we’ll be building:
Logging In to Stream
Create a free Stream account or sign in to your existing account here. Once you’re logged in, create a new application and take note of your App Access Keys which we’ll be making use of shortly.
Setting Up Your React App
Open the terminal on your computer and run the following command to bootstrap a new React application:
npx create-react-app stream-web-notifications
Once the command finishes running,
cd into the newly created directory and install the following dependencies, which will be needed in the course of fleshing out our demo application:
$ npm install express cors dotenv body-parser random-username-generator stream-chat stream-chat-react axios
After the dependencies are installed, you can start the development server using
npm start which should open it up on http://localhost:3000!
Setting Up Your Server
Before we can build the application frontend, we need to set up an Express server for the purpose of creating users on our Stream instance and resolving special tokens, which are used to authenticate the user.
Create a new
server.js in the root of your project directory and populate it with the following code:
The code above allows us to receive a
username from the client, and create the
user on our Stream chat instance, passing in the token for the
user. The token is also included in the response, allowing us to use it to initialise the user in our React application.
Before we can start the server, we need to set some environmental variables. Create a
.env file in the project and paste your Stream application credentials (which you grabbed when you logged in to your account) into the file in the following format:
Now go ahead and start your server on port
Building Your Application Frontend
Our application code will be quite simple, thanks to our use of Stream’s React components, which enable us to compose a rich chat interface with only a few lines of code. Here’s all the code we'll need to build out the UI for our chat app:
And there you go... With just the lines of code above, we have a fully responsive chat UI that supports advanced chat functionality, such as typing indicators, emoji, reactions, file uploads, rich link preview, user presence and more!
With this code, we’re generating a random
username each time the page is loaded, so we don’t have to go through a complicated sign-in process to see the app in action. This also makes it easy to spawn multiple users quickly and to simulate a chat session between them.
In the next section, we’ll consider how to display notifications when messages are sent and received between users.
Enabling Browser Notifications for New Messages
Let’s prompt the user to enable browser notifications by displaying a banner at the top of the page, similarly to the way it’s done in Slack. Update the code in
src/App.js as follows:
You'll also need to add some styles for the banner in your
src/App.css file as shown below:
setNotificationBanner hook helps us determine whether to show the alert banner or not. If the user hasn’t granted or denied permission, the banner is shown and, once it's clicked, a prompt is displayed by the browser asking the user to block or allow notifications from the app.
Now that notifications are enabled, the next thing to figure out is a way to display notifications when a user has a new unread message. One method we’ll employ is to change the favicon on the browser window, to give the user multiple indications that a message or few has not yet been read, which is a common technique employed by many web applications today! Once all the messages have been read, we’ll revert back to the normal favicon.
public/index.html file and add an
favicon to the favicon
Following that, update your
src/App.js file as shown below:
The relevant changes are between
lines 53-66. Stream provides an easy way to listen for events on a channel; you can listen for a specific event or for all events, as we’re doing above.
message.new event is triggered, and the
unread_count is greater than 0, we display a notification for the user and set the favicon to a bell icon. Checking the value of
unread_count is necessary because we don’t want to display a notification for messages that have already been read.
Secondly, if the
message.read event is triggered, and the
total_unread_count is falsy (set to 0 or
null), we revert to the regular favicon; if the
total_unread_count is falsy, it is an indication that the user has no unread messages.
You can try out your handiwork by using two different browsers to send messages between users. It should send notifications and update the favicons appropriately. You will also notice that the title of the window is updated with the number of unread messages that a user has. This is an automatic feature that we get just by making use of Stream’s React components!
In this tutorial, we’ve described how to set up real time browser notifications for incoming messages with Stream. The Stream Chat docs contain more information on the various types of events that can be listened for, so be sure to check it out to see everything that’s available to you!
The complete source code used in this tutorial can be found in the GitHub repository. Thanks for reading!