Send push notifications to your browser from Adonis.js
You will need Node installed on your machine.
Introduction
In this tutorial, I will show how to send push notifications to your browser from your backend. We’ll use Adonis.js as our Node.js framework, and we’ll push notifications from our Adonis app to our browser through Pusher channels.
Web push notifications are an instant means of direct communication between a website and its customers. They appear as clickable messages on web browsers in desktop and Android devices. This is the easiest way to gather more subscribers without collecting email IDs and contact details.
Demo
Here is the final result of our app:
Prerequisites
In order to follow this tutorial, knowledge of JavaScript and Node.js, more precisely Adonis.js is required. You should also have the following installed on your machine:
Set up your Adonis project
Open your terminal and type this command to install Adonis CLI:
# if you don't have Adonis CLI installed on your machine.
$ npm install -g @adonisjs/cli
# Create a new adonis app and move into the app directory
$ adonis new adonis-push-notifications && cd adonis-push-notifications
Start the server and test if it’s working:
$ adonis serve --dev
2018-10-18T09:09:16.649Z - info: serving app on http://127.0.0.1:3333
Edit the welcome view
Go to the resources/views
directory and replace the content of welcome.edge
file with:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Hello Adonis</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/css/bootstrap.min.css">
{{ style('style') }}
</head>
<body>
<div id="app" class="container" style="margin-top: 160px">
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
<div class="card">
<div class="card-header">Broadcast a Notification message</div>
<div class="card-body">
<div class="container">
<div class="row justify-content-md-center">
<div class="col col-md-10">
@if(old('status'))
<div class="alert alert-success" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
{{ old('status') }}
</div>
@endif
<form method="POST" action="{{ route('sendNotification') }}">
{{ csrfField() }}
<div class="form-group row">
<label class="col-md-3 col-form-label">
Notification Message
</label>
<div class="col-md-9">
<input type="text" name="message" placeholder="Send Notification"
autocomplete="off"
class="form-control" required>
</div>
</div>
<div class="form-group row">
<div class="col-md-3"></div>
<div class="col-md-6">
<button type="submit" class="btn btn-primary btn-block">
<i class="fa fa-btn fa-paper-plane"></i> Send Notification
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{ script('https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js') }}
{{ script('https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/js/bootstrap.min.js') }}
</body>
</html>
As you can see, we are importing the CSS files using the css
method. We do a similar thing with JavaScript, we use script
method to import .js
. Flash messages are used to display incoming messages from the server. Flash messages are stored temporarily in sessions by the server to display as browser notifications.
Refresh your browser:
Install the Pusher SDK
Go to Pusher and create an account or sign in if you already have an account.
Next, create a new Pusher app instance. This registration provides credentials which can be used to communicate with the created Pusher instance. Copy the App ID, Key, Secret, and Cluster from the App Keys section and put them in the .env
file located at you project root:
//.env
PUSHER_APP_KEY=<APP_KEY>
PUSHER_APP_SECRET=<APP_SECRET>
PUSHER_APP_ID=<APP_ID>
PUSHER_APP_CLUSTER=<APP_CLUSTER>
We’ll use these keys further in this tutorial to link Pusher with our Adonis project.
Next, we need to install the Pusher SDK as well as other dependencies we need to build our app.
We won’t use the Pusher SDK directly but instead use a Pusher provider for Adonis. This provider enables us to use the Pusher SDK easily with the Adonis.js ecosystem. We should first install the Pusher SDK by running this command:
#if you want to use npm
npm install pusher
#or if you prefer Yarn
yarn add pusher
Now, you can install the Pusher provider for Adonis with this command:
#if you want to use npm
npm install adonis-pusher
#or if you prefer Yarn
yarn add adonis-pusher
You will need to add the provider to AdonisJS at start/app.js
:
const providers = [
...
'adonis-pusher/providers/Pusher'
]
Define routes and your controller
In order to make requests to our backend, we need to define our routes and a controller responsible for the logic our app should have.
Type this command in your terminal to create your controller: adonis:make Notification
.
Open the routes.js
file located at ../start/routes.js
and replace the existing code with the following:
const Route = use('Route')
const Event = use('Event')
Route.on('/').render('welcome')
Route.post('/sendNotification','NotificationController.sendNotification').as('sendNotification')
The first two lines pull in the Route
and Event
providers for us. Next we tell our app to render the welcome.edge
view to the /
get request. And the last route accepts a message from the client and defines the sendNotification
function (which we’ll create very soon) for handling the logic.
Now, let’s create our sendNotification
function we talked about earlier. Paste this piece of code inside your NotificationController
file:
//../app/Controllers/Http/NotificationController.js
'use strict'
const Event = use('Event');
class NotificationController {
async sendNotification({request, session, response}) {
let message = request.input('message');
Event.emit('send::notification', message)
session.flash({status: 'Notification sent'})
return response.redirect('back')
}
}
module.exports = NotificationController
We first pull in the Event
service provider, then we accept a message from the client post request.
Last we emit an event named send::notification
and redirect the user back with a flash message.
Connecting Adonis and Pusher
Create a filename event.js
in the start
directory. In this file we’ll create an event which will be fired every time we need to send a message via Pusher Channels, and as it happens a notification via Pusher Channels.
//../start/events.js
const Event = use('Event')
const Env = use('Env')
const Pusher = use('Pusher')
let pusher = new Pusher({
appId: Env.get('PUSHER_APP_ID'),
key: Env.get('PUSHER_APP_KEY'),
secret: Env.get('PUSHER_APP_SECRET'),
cluster: Env.get('PUSHER_APP_CLUSTER'),
encrypted: false
})
//fire new event
Event.when('send::notification', async (message) => {
pusher.trigger('notification-channel', 'new-notification', {
message
})
})
We need to pull in the Event
, Pusher
(using the adonis-pusher package we installed earlier) and Env
service providers.
Next, we registered a listener for the send::notification
event, after which we initialized and configure Pusher. This event was registered in the sendNotification
function we created above to handle notification post.
When we are done with the pusher configuration, we trigger a new-notification
event on the notification-channel
with the trigger
method.
Subscribing to Pusher Events and send notifications
The client needs to start listening to these events being emitted by Pusher. Go to the resources/views
directory and update your welcome.edge
by adding the following code:
<!-- Include the Pusher Client library -->
{{ script('https://js.pusher.com/4.3/pusher.min.js') }}
<script>
//Open a connection to Pusher
let notify = ({message}) => {
if (!("Notification" in window)) {
alert("This browser does not support desktop notification");
}
Notification.requestPermission().then(function (result) {
if (result === 'granted') {
let notification = new Notification(message)
}
});
};
let pusher = new Pusher(YOUR_PUSHER_APP_ID, {
cluster: YOUR_PUSHER_CLUSTER,
encrypted: false
});
//Subscribe to the channel we specified in our Adonis Application
let channel = pusher.subscribe('notification-channel');
//Listen for events on the channel
channel.bind('new-notification', (data) => {
notify(data)
})
</script>
First, we include the Pusher client library in order to use Pusher instance from our browser.
As you can see we also create a notify
function. This function takes the message we intend to send as a push notification in parameter, checks if browser push notifications are supported by the browser and display a new notification to us.
Next, we initialize the Pusher service by passing in our App Key (replace with your actual keys), and some other options (cluster, encrypted). The initialized instance is used to subscribe to the notification-channel
channel.
Finally, we listened to the new-notification
event and send notifications with the notify
function we created earlier.
Conclusion
In summary, we learned how we can use Pusher channels to send notifications from an Adonis.js backend. Events sent by Pusher channels are listened on the client side and displayed as a push notifications using browser notifications web API. You can find the full source code on GitHub here.
6 December 2018
by Ethiel Adiassa