How to Implement Push Notifications in PWA using React
Real-world example for push notification implementation with React and PostgreSQL database
Push notifications are such a powerful tool to make engagement with users stronger and motivate them to come back to your app more often. My team and I created a mobile-friendly virtual pet game that doubles as a health habit tracker. We wanted to send users reminders for healthy daily routines such as ‘drink water’, ‘move your body around’ or ‘take a break from your screen’, etc.
To implement the feature, we decided to make the app a Progressive Web apps, so that it can be accessible from any device along with native-like features such as push notifications and offline access.
While I was researching, I found very helpful tutorials and articles for the basics of how Service Workers work and interact with the push API, but it was hard to find a resource that explains how it works with a React project in a deployed environment. So I wanted to share my experience here in case someone is facing a similar challenge. If you are seeking to learn the basics of Push notifications in PWA, I recommend checking out this tutorial. This article is also helpful to see the overview.
Project Tech Stack: React, Redux, Node.js, Express, PostgreSQL, Sequelize, Webpack. Heroku, Heroku Postgres
Objective: To be able to send push notifications to multiple users by sending API requests via the API developer platform such as Postman.
Starting point:
- Made a new project on Firebase and got the Server key ready.
- Had my VAPID key ready. If you are not familiar, please check out this tutorial first.
- Had my Service Worker file with the event listener for push event. Below is the sample code
If you are not familiar with how to set up Service Workers, check out the install section of this article.
Step 1: Think about the user story
A user story is always a good starting point to think about the app’s functionality and UI. Diagraming is one of the ways to do it and it’s a great tool to share your thought with your team member.
At the very beginning, I made the diagram to visualize the user story of the whole web push cycle to clarify both the subscription process and sending push message process. That helped me to understand how Service Worker works to get user’s subscription and how the push messages finally are sent to user’s devices.
Step 2: Create a modular function that handles subscriptions
To handle the subscription process, I created a modular function that includes the following functionalities.
- Register Service Worker
- Check the user’s opt-in status
- Ask browser permission for notifications
- Subscribe users
- Unsubscribe users
- Update database accordingly
This function takes care of the user story for the subscription process all in one place. So that I can mount this function wherever it makes sense to manage the user’s subscription.
For the code sample, please check out this gist I created. Here is the code sample for the API route.
Step 3: Decide the place and timing to call the subscription function.
Where and when to call the subscription function may vary depending on the specifics of your app. In my experience, within a React component, the inside of the lifecycle method seems to be a good place to call the function.
On our app, the home page component was the best place to check the user’s subscription status because every user will visit the page when they use the app. So I imported the ‘handleSubscription’ function in the component and placed it inside of the componentDidMount method so that each time the home page is rendered, the Service Worker gets registered and updates the user’s subscription status.
Step 4: Integrate Push API within the App server
Now, we have users’ subscriptions in our database, so let’s send a push notification to them!
To do this, I created an API route to receive requests from Postman. This triggers sending push messages to the Service Worker, which is located in the users’ browser that stores the subscription. Inside of the route, I used web-push as push API to send push notifications to Service Workers.
Service Worker’s push event listener will be fired when it receives this push event. You can then invoke the showNotification method to send the message to the device’s system.
In the above sample, the VAPID key is assigned as an actual value, but to make it secure, it should be replaced as an environment variable. That way no one can see it from your codebase.
Step 5: Authorize your API request
Finally, the app is ready to send push notifications to users. the last step was adding the authorization key to the request header of the request that I’m sending via Postman. Firebase Cloud Message (FCM) added this security to make sure that only authorized requests can be delivered to Service Worker. You can find your authorization key on the firebase console setting page as a server key.
After authorizing the request, click the send button.
And….I got the notification!
The learning process was not easy, but it was a great experience to know how PWA and Service worker works. I hope you found this helpful, please leave a comment with your experience!