How to Add Real-Time Notifications to Laravel with Pusher
https://www.sitepoint.com/add-real-time-notifications-laravel-pusher/
Last updated
https://www.sitepoint.com/add-real-time-notifications-laravel-pusher/
Last updated
This article was peer reviewed by Rafie Younes and Wern Ancheta. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!
The modern web user expects to be informed of everything that happens within the application. You don’t want to be that one website that doesn’t even have the notifications dropdown found not just in all social media websites, but everywhere else these days, too.
Luckily, with Laravel and Pusher, implementing this functionality is a breeze. The code we’ll write in this tutorial can be found here.
Image via Pusher.com
In order to provide users with a good experience, notifications should to be shown in real-time. One approach is to send an AJAX request regularly to the back end and fetch the newest notifications if they exist.
A better approach is to leverage the power of WebSockets, and receive notifications the moment they are sent. This is what we’re going to use in this tutorial.
Pusher is a web service for
… integrating realtime bi-directional functionality via WebSockets to web and mobile apps.
It has a very simple API, but we’re going to make using it even simpler with Laravel Broadcasting and Laravel Echo.
In this tutorial, we’re going to add real-time notifications to an existing blog. The basic functionality is similar to Real-Time Laravel Notifications with Stream. We’ll start off with this repo made by Christopher Vundi (I changed it just a bit) which is a simple blog where users that can perform CRUD on posts.
First we’ll clone the simple Laravel blog:
Then we’ll create a MySQL database and set up environment variables to give the application access to the database.
Let’s copy env.example
to .env
and update the database related variables.
.env
Now let’s install the project’s dependencies with
And run the migration and seeding command to populate the database with some data:
If you run the application and visit /posts
you’ll be able to see a listing of generated posts.
Check the application, register a user, and create some posts. It’s a very basic app, but serves our demo perfectly.
Let’s make a pivot table that relates users to users. Make a new followers
migration:
We need to add some fields to that migration: a user_id
to represent the user who is following, and a follows_id
field to represent the user who’s being followed.
Update the migration as follows:
Now let’s migrate to create the table:
If you have followed the Stream approach article you’ll find that things are almost identical up to this point. In the part that follows, we’re going to achieve the same follow functionality with a different approach.
Let’s add relationships methods to the User
model.
app/User.php
Now that the user model has the necessary relationships, followers
returns all the followers of a user, and follows
returns everyone the user is following.
We’ll be needing some helper functions to allow the user to follow
another user, and to check whether a user isFollowing
a specific user.
app/User.php
Perfect. With the model set, it’s time to list users.
Let’s start by setting the necessary routes
routes/web.php
Then, it’s time to create a new controller for users:
We’ll add an index
method to it:
app/Http/Controllers/UsersController.php
The method needs a view. Let’s create the users.index
view and put this markup in it:
resources/views/users/index.blade.php
You can now visit the /users
page to see a listing of users.
The UsersController
lacks follow
and unfollow
methods. Let’s get them done to wrap this part up.
app/Http/Controllers/UsersController.php
We’re done with the follow functionality. We can now follow and unfollow users from the /users
page.
Laravel provides an API for sending notifications through multiple channels. Emails, SMS, web notifications, and any other type of notifications can all be sent using the Notification class.
We are going to have two types of notifications:
Follow notification: sent to a user when they get followed by another user
Post created notification: sent to the followers of a given user when they create a new post
User Followed Notification
Using artisan commands, we can generate a migration for notifications:
Let’s migrate and create this new table.
We’re starting with follow notifications. Let’s execute this command to generate a notification class:
Then we’ll update the notification class file we just created:
app/Notifications/UserFollowed.php
With these few lines of code we can achieve a lot. First we’re requiring an instance of the $follower
to be injected when this notification is created.
Using the via
method, we’re telling Laravel to send this notification via the database
channel. When Laravel encounters this, it will create a new record in the notifications table.
The user_id
and notification type
are automatically set, plus we can extend
the notification with more data. That’s what toDatabase
is for. The returned array will be added to the data
field of the notification.
Finally, by implementing ShouldQueue
, Laravel will automatically put this notification inside a queue to be executed in the background, which will speed up the response. This makes sense because we will be adding HTTP calls when we use Pusher later on.
Let’s initiate the notification when the user gets followed.
app/Http/Controllers/UsersController.php
We could call the notify
method on a User
model because it is already using the Notifiable trait.
Any model you want to notify should be using it to get access to the notify
method.
Mark a Notification as Read
Notifications will contain some information and a link to a resource. For example: when a user receives a notification about a new post, the notification should show an informative text, redirect the user to the post when clicked, and be flagged as read.
We’re going to make a middleware that checks if a request has a ?read=notification_id
input and flag it as read.
Let’s make a middleware with the following command:
Then, let’s put this code inside the handle
method of the middleware:
app/Http/Middleware/MarkNotificationAsRead.php
In order to get our middleware to be executed for each request, we’ll add it to $middlewareGroups
.
app/Http/Kernel.php
With that done, let’s show some notifications.
Showing Notifications
We have to show a listing of the notifications using AJAX, then update it in real time with Pusher. First, let’s add a notifications
method to the controller:
app/Http/Controllers/UsersController.php
This will return the last 5 unread notifications. We just have to add a route to make it accessible.
routes/web.php
Now add a dropdown for notifications in the header.
resources/views/layouts/app.blade.php
We’ve also added a global window.Laravel.userId
variable inside a script to get the current user’s ID.
JavaScript and SASS
We’re going to use Laravel Mix to compile JavaScript and SASS. First, we need to install npm packages.
Now let’s add this code into app.js
:
app/resources/assets/js/app.js
This is just an initialization. We’re going to use notifications
to store all notification objects whether they’re retrieved via AJAX or Pusher.
You probably guessed it, NOTIFICATION_TYPES
contains types of notifications.
Next, let’s “GET” notifications via AJAX.
app/resources/assets/js/app.js
With this, we’re getting the latest notifications from our API and putting them inside the dropdown.
Inside addNotifications
we concatenate the present notifications with the new ones using Lodash, and take only the latest 5 to be shown.
We need a few more functions to finish the job.
app/resources/assets/js/app.js
This function builds a string of all notifications and puts it inside the dropdown. If no notifications were received, it just shows “No notifications”.
It also adds a class to the dropdown button, which will just change its color when notifications exist. It’s a bit like Github’s notifications.
Finally, some helper functions to make notification strings.
app/resources/assets/js/app.js
Now we’ll just add this to our app.scss
file:
app/resources/assets/sass/app.scss
Let’s compile assets:
If you try and follow a user now, they’ll get a notification. When they click it, they’ll be redirected to /users
, plus the notification will disappear.
We’re going to notify followers when a user creates a new post.
Let’s start by generating the notification class.
Let’s update the generated class as follows:
app/Notifications/NewArticle.php
Next, we need to send the notification. There are several ways we could do this. I like to use Eloquent Observers.
Let’s make an observer for Post
and listen to its events. We’ll create a new class: app/Observers/PostObserver.php
Then, register the observer in AppServiceProvider
:
app/Providers/AppServiceProvider.php
Now we just need to format the message to be shown in JS:
app/resources/assets/js/app.js
And voilà! Users are getting notifications about follows and new posts! Go ahead and try it out!
It’s time to use Pusher to get notifications in real-time through websockets.
Sign up for a free Pusher account at pusher.com and create a new app.
Set your account’s options inside the broadcasting
config file:
config/broadcasting.php
Then we’ll register App\Providers\BroadcastServiceProvider
in the providers array.
config/app.php
We should install Pusher’s PHP SDK and Laravel Echo now:
We have to set the notification data to be broadcast. Let’s update the UserFollowed
notification:
app/Notifications/UserFollowed.php
And NewPost
:
app/Notifications/NewPost.php
The last thing we need to do is update our JS. Open app.js
and add the following code
app/resources/assets/js/app.js
And we’re done here. Notifications are being added in real-time. You can now play with the app and see how notifications get updated.
Pusher has a very simple API that makes receiving real-time events incredibly easy. Coupled with Laravel notifications, we could send a notification through multiple channels (email, SMS, Slack, etc.) from one place. In this tutorial, we added user-following functionality to a simple blog, and enhanced it with the aforementioned tools to get some smooth real-time functionality.
There’s a lot more to Pusher and to Laravel notifications: in tandem, the services allow you to send pub/sub messages in real time to browsers, mobiles, and IOT devices. There’s also a presence API to get online/offline status of users.
Please check their respective documentations (Pusher docs, Pusher tutorials, Laravel docs) to explore them in more depth and utilize their true potential.
Let me hear what you’ve built with these technologies in the comments.
We want to give users the ability to follow other users, and be followed by users, so we have to create a Many To Many
relationship between users to make it happen.