.. using Push API and Firebase.
The Push API
is currently supported
by Chrome, Edge and Firefox. Chrome v. 76 was used for the examples and
prototypes described in this document.
- The web application's HTTP server serves it's documents via a secure HTTPS connection.
- All certificates used for transport encryption (HTTPS/SSL) must be valid.
- Otherwise (e.g. for development purposes) the browser has to be started explicitly unsecured like:
google-chrome --user-data-dir=/tmp/foo --ignore-certificate-errors --unsafely-treat-insecure-origin-as-secure=<your-host>
- Ensure browser notifications are not globally disabled in your browser settings.
To create a Firebase
account, you need a google account first.
With that you can log in on console.firebase.google.com.
Now enter an existing Firebase
project by selecting the respective
project on your dashboard or create a new project via
the Create a project
button.
After entering the project, click on the gear symbol right next to Project Overview
at the top of the left sidebar and click on the Project settings
link.
You should now see some general settings for your project
and a Your apps
section at the bottom of the page.
- If you have not created an app at all: Click on the a web application
symbol
</>
in theYour apps
list at the bottom of the page to create a new web application. - If you have already created at least one app: Click on the
Add app
button to create an further app, or choose the respective app from theWeb apps
list.
After selecting an app you see multiple information on the right.
Copy the CDN HTML code, which is shown directly below Firebase SDK snippet
.
It should look similar to this:
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/6.5.0/firebase-app.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#config-web-app -->
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyBqyAcC_NCX3hmqah3WEq8oCTRttHYxYy8",
authDomain: "push-notifications-d6997.firebaseapp.com",
databaseURL: "https://push-notifications-d6997.firebaseio.com",
projectId: "push-notifications-d6997",
storageBucket: "",
messagingSenderId: "112067727973",
appId: "1:112067727973:web:d82edfa3dc7a06bb"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
If you do not want to use a CDN you can also download the JavaScript file.
To enable your web application to handle push notifications you have to integrate the SDK snippet into your frontend HTML documents and add a few more things.
First of all you have to register a Service Worker
.
If you do not have any Service Worker
yet, you can add the firebase-messaging-sw.js
file from the ([Firebase SDK
] (you can find useful links for integration here or
here).
to your application's root directory.
In ILIAS the integration or implementation of a Service Worker
will have
strong correlations to the Concept ILIAS Offline, because each web application
can only register one Service Worker
.
If your application already implements a Service Worker
it has to be open
for extended push notification JavaScript code by offering respective slots
for other components.
In this firebase-messaging-sw.js
file you can define all event listeners
your push notifications should react to. After this you need
the firebase-messaging.js
to be included in your HTML document.
You should include it right after the firebase-app.js
in your SDK snippet:
<script src="https://www.gstatic.com/firebasejs/6.5.0/firebase-messaging.js"></script>
Now you should be able to create a messaging object below the initializeApp
in the SDK snippet.
const messaging = firebase.messaging();
You have to connect the service worker to your Firebase
project server.
In order to do that you need your public VAPID
key.
- VAPID is a secure protocol communication between the server and the service worker.
- It is published by Google and a proposed standard for IETF.
To get the key, go to your Firebase
project setting and enter the tab Cloud Messaging
.
You have to scroll down to Web configuration
.
In the box on the right (below Web Push certificates
) you should see a key called Key pair
.
If not, create one.
Then copy the key and inject it into your SDK snippet right below the creation of the messaging object.
messaging.usePublicVapidKey('<your-key>');
For a public web app it is necessary that you ask the user for permission to send notifications.
Therefore, you have to add the function messaging.requestPermission()
and wrap the connection process.
messaging.requestPermission();
if(Notification.permission === 'granted'){
messaging.usePublicVapidKey('<your-key>');
} else {
console.error('Notifications disabled!');
}
To send a message to all registered service workers you need to get the token
from one of the service workers.
For this you have to call the promise-function messaging.getToken()
after your integration.
messaging.getToken().then((currentToken) => {});
The response of the promise passed as argument is the actual token.
When you combine the token with the default Firebase
cloud messaging
send url (https://fcm.googleapis.com/fcm/send/) you get your personal
endpoint for your push notifications.
messaging.getToken().then((currentToken) => {
var endpoint = 'https://fcm.googleapis.com/fcm/send/' + currentToken;
}).catch((err) => {
console.error('Subscription failed!');
});
You can now send notification requests to that endpoint.
To authenticate the request you need one of your Firebase
server keys.
You can find those in your Firebase
project settings in the tab Cloud Messaging
.
You can use the Legacy Server key
, but its recommended to add/use a new Server key
.
It is possible to create multiple Server keys
for different purposes.
With the endpoint and the Server key
you are now able to trigger push notifications
on all active service workers.
Therefore, you can use any valid communication method.
In the following example, CURL is used on a command line interface.
curl "<your-endpoint>" --request POST --header "TTL: 60" --header "Content-Length: 0" --header "Authorization: key=<your-server-key>"
This may be a little bit different between different browsers.
This one is for Chrome. For Firefox, for example, you do not have to send the Authorization header
.
With this the communication of the server and service worker is finished.
To react to an incoming request you have to define an event listener in your firebase-messaging-sw.js
.
This works just like regular event listeners.
The following example listens to a push request and displays a notification:
self.addEventListener('push', function(event) {
self.registration.showNotification('Push Notification', {})
});
The second parameter of the showNotification
is an option array.
With that you can change the notification behavior (just like mobile vibration, etc.
all options can be tested here).
To update the registered service worker just refresh your browser.
With this you should always see a visual push notification as long as you have a browser with an active service worker running.
- In most cases, if you cannot get a token for your endpoint, this is caused by insufficient notification permissions.
- You can check the permission with
Notification.permission
(should be'granted'
). - You can reset the permission with a right click on the prefix in your browsers URL bar or in your browser settings.
- You can check the permission with
If your (for Example CURL) request is responded with something like "bad request" or "wrong authentication" in most cases your endpoint-token has changed. This can happen if you updated your service worker but did not replace it with a new one. In this case just update your endpoint-token in your request.
For some browsers there are minor differences in the implementation or in the accepted request. Push notifications do not work in Safari or IE.
There are some possible variations in the implementation progress:
- There are ways to implement notifications without the
Firebase API
or even withoutFirebase
.- An example using the web-push node.js library can be found here.
- It's possible to send push notifications without VAPID, but it is not recommended.
- The sending progress can be done with the
Firebase API
, too. But it is not recommended because the layers of incoming request should be kept abstract.