├── .gitignore ├── routes └── token_routes.js ├── server.js ├── package.json ├── app ├── index.html ├── notification.js └── firebase-messaging-sw.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | config.js 3 | -------------------------------------------------------------------------------- /routes/token_routes.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const jsonParser = require('body-parser').json(); 3 | 4 | var tokenRouter = module.exports = exports = express.Router(); 5 | 6 | // Simple route to accept token from user 7 | tokenRouter.post('/setToken', jsonParser, (req, res) => { 8 | console.log('TOKEN RECEIVED: ' + req.body.token); 9 | }); 10 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | 4 | const PORT = process.env.PORT || 3000; 5 | 6 | const tokenRouter = require(__dirname + '/routes/token_routes'); 7 | 8 | app.use('/api', tokenRouter); 9 | app.use('/', express.static(__dirname + '/app')); 10 | 11 | module.exports = exports = app.listen(PORT, () => { 12 | console.log('Server running on port: ' + PORT); 13 | }); 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-firebase-notifications", 3 | "version": "1.0.0", 4 | "description": "Simple firebase push notifications web app using Firebase Cloud Messaging (FCM) JavaScript API", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node server.js" 9 | }, 10 | "author": "Sabrina Tee", 11 | "license": "MIT", 12 | "dependencies": { 13 | "body-parser": "^1.15.2", 14 | "express": "^4.14.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | Notifications Test 3 | 4 |

5 | Hello Notifications! 6 |

7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/notification.js: -------------------------------------------------------------------------------- 1 | // Initialises firebase 2 | // TODO: fill in firebase config information 3 | var config = { 4 | apiKey: "", 5 | authDomain: "", 6 | databaseURL: "", 7 | storageBucket: "", 8 | messagingSenderId: "" 9 | }; 10 | 11 | firebase.initializeApp(config); 12 | var messaging = firebase.messaging(); 13 | 14 | // On load register service worker 15 | if ('serviceWorker' in navigator) { 16 | window.addEventListener('load', () => { 17 | navigator.serviceWorker.register('/firebase-messaging-sw.js').then((registration) => { 18 | // Successfully registers service worker 19 | console.log('ServiceWorker registration successful with scope: ', registration.scope); 20 | messaging.useServiceWorker(registration); 21 | }) 22 | .then(() => { 23 | // Requests user browser permission 24 | return messaging.requestPermission(); 25 | }) 26 | .then(() => { 27 | // Gets token 28 | return messaging.getToken(); 29 | }) 30 | .then((token) => { 31 | // Simple ajax call to send user token to server for saving 32 | $.ajax({ 33 | type: 'POST', 34 | url: '/api/setToken', 35 | dataType: 'json', 36 | data: JSON.stringify({token: token}), 37 | contentType: 'application/json', 38 | success: (data) => { 39 | console.log('Success ', data); 40 | }, 41 | error: (err) => { 42 | console.log('Error ', err); 43 | } 44 | }) 45 | }) 46 | .catch((err) => { 47 | console.log('ServiceWorker registration failed: ', err); 48 | }); 49 | }); 50 | } 51 | -------------------------------------------------------------------------------- /app/firebase-messaging-sw.js: -------------------------------------------------------------------------------- 1 | importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-app.js'); 2 | importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-messaging.js'); 3 | 4 | // TODO: fill in messaging sender id 5 | firebase.initializeApp({ 6 | 'messagingSenderId': 'FIREBASE_SENDER_ID' 7 | }); 8 | 9 | const messaging = firebase.messaging(); 10 | 11 | // Installs service worker 12 | self.addEventListener('install', (event) => { 13 | console.log('Service worker installed'); 14 | }); 15 | 16 | self.addEventListener('notificationclick', (event) => { 17 | // Event actions derived from event.notification.data from data received 18 | var eventURL = event.notification.data; 19 | event.notification.close(); 20 | if (event.action === 'confirmAttendance') { 21 | clients.openWindow(eventURL.confirm); 22 | } else { 23 | clients.openWindow(eventURL.decline); 24 | } 25 | }, false); 26 | 27 | messaging.setBackgroundMessageHandler((payload) => { 28 | // Parses data received and sets accordingly 29 | const data = JSON.parse(payload.data.notification); 30 | const notificationTitle = data.title; 31 | const notificationOptions = { 32 | body: data.body, 33 | // icon: '/static/images/5/icons/android-icon-96x96.png', 34 | actions: [ 35 | {action: 'confirmAttendance', title: '👍 Confirm attendance'}, 36 | {action: 'cancel', title: '👎 Not coming'} 37 | ], 38 | // For additional data to be sent to event listeners, needs to be set in this data {} 39 | data: {confirm: data.confirm, decline: data.decline} 40 | }; 41 | 42 | return self.registration.showNotification(notificationTitle, notificationOptions); 43 | }); 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # simple-firebase-notifications 2 | 3 | ### Get Started 4 | 5 | 1. Clone this repo 6 | 2. npm install 7 | 3. Fill in your firebase keys in: 8 | - firebase-messaging-sw.js 9 | - notification.js 10 | 4. node server.js 11 | 5. Open your browser to localhost:3000 12 | 6. Upon opening your browser, the service worker should have installed and automatically sent your browser token to the server. You will need the token to send notifications to your browser (limited browser support, see limitations below) 13 | 14 | 15 | ### Sending Notifications 16 | 17 | 1. curl from your terminal: 18 | ``` 19 | curl -X POST --header "Authorization: key=[FIREBASE_SERVER_KEY]" --Header "Content-Type:application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"[BROWSER_TOKEN_KEY]\",\"data\":{\"notification\":{\"body\":\"Are you coming to our party?\",\"title\":\"This is a tester tester\",\"confirm\":\"https://developers.google.com/web/\",\"decline\":\"https://www.yahoo.com/\"}},\"priority\":10}" 20 | ``` 21 | - make sure to enter your [firebase authorization key (your server key)](https://firebase.google.com/docs/cloud-messaging/server#auth) in the field of 'Authorization: key=' and your browser token in the 'to' field (don't include the []) 22 | - to ensure your data is passed through correctly, ensure your body looks like: 23 | ``` 24 | "{ 25 | "to": "", //browser token here 26 | "data": { 27 | "notification": { 28 | "body": "Are you coming to our party?", 29 | "title": "This is a tester tester". 30 | "confirm": "https://developers.google.com/web/", 31 | "decline": "https://www.yahoo.com/" 32 | } 33 | }, 34 | "priority": 10 35 | }" 36 | ``` 37 | 38 | ### Limitations 39 | 40 | According to [Firebase documentation](https://firebase.google.com/docs/cloud-messaging/js/client): The FCM JavaScript API lets you receive notification messages in web apps running in these browsers: 41 | - Chrome: 50+ 42 | - Firefox: 44+ 43 | - Opera Mobile: 37+ 44 | --------------------------------------------------------------------------------