U ovom ćemo blog postu napraviti Node.js API za slanje Push notifikacija. Ovaj API je samo jedan dio svega onoga što je potrebno zadovoljiti kako bi se push notifikacije mogle uspješno slati/primati i biti će zapravo nadogradnja prethodnog Node.js API-ja za upload datoteka.
Proces slanja push notifikacija:
- Treba nam servis koji će stajati između API-ja i mobilne aplikacije. U ovom slučaju to je Google Firebase.
- Treba nam jedinstveni token mobilne aplikacije tj. uređaja kako bi API znao kome poslati push notifikaciju. Kreiranje jedinstvenog tokena odvija se u samoj mobilnoj aplikaciji i to neće biti pokriveno ovim blog postom.
- Treba nam API koji će na osnovu zahtjeva skupiti sve tokene i poslati im push notifikaciju. Za to ćemo koristiti node-gcm NPM paket.
U nekom od sljedećih blog postova napravit ćemo primjer Ionic aplikacije koja će koristiti ovaj API tj. koja će zapravo primati push notifikacije.
Google Firebase
Google Firebase ćemo koristiti kao servis koji će stajati između mobilne aplikacije i Node.js API-ja. Na adresi https://console.firebase.google.com/ potrebno je napraviti novi projekt s nazivom mobilne aplikacije koja će API koristiti.
Server key će nam trebati u server.js kako bi naš API znao s kojim servisom će komunicirati.
Osim toga potrebno je još dodati podršku za konkretne platforme na kojima će se temeljiti mobilna aplikacija jer svaka platforma ima svoje specifičnosti. S obzirom da je Ionic framework za izradu hibridnih mobilnih aplikacija mi ćemo odmah kreirati podršku za iOS i Android platforme.
Priprema za Android platformu
Priprema za iOS platformu
Što se Google Firebasea tiče to je za sada to. Njemu ćemo se vratiti kada budemo radili mobilnu aplikaciju jer će nam trebati još neki podaci.
Testni push.js
Sada ćemo napraviti testni push.js s kojim ćemo isprobati radi li uopće naš API i hoće li push notifikacija stići na mobilni uređaj.
Prvo moramo instalirati https://www.npmjs.com/package/node-gcm pomoću naredbe $ npm install node-gcm --save.
gcmApiKey je zapravo server key koji imamo unutar Google Firebase sučelja, ali ovdje nam treba i jedinstveni token uređaja, a njega dobijemo unutar mobilne aplikacije. Kako dobiti taj token neću prikazati u ovom blog postu nego u nekom od sljedećih. Uglavnom, na slici se vidi token uređaja.
Njega dobijemo na način da buildamo aplikaciju na mobilni uređaj i unutar chrome://inspect/#devices otvorimo konzolu iz koje kopiramo token koji onda zalijepimo u push.js
Sada imamo sve potrebno unutar push.js kako bi testirali API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
var express = require('express'); var gcm = require('node-gcm'); var app = express(); var gcmApiKey = 'xxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx--xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx-xx'; // Server key iz https://console.firebase.google.com/ var server = app.listen(3001, function () { console.log('Pokrenut testni push API server!'); }); app.get('/', function (req, res) { res.send("Defaultna ruta"); }); app.get('/push', function (req, res) { var device_tokens = []; // array jedinstvenih tokena uređaja var retry_times = 4; // broj puta koliko će se push notifikacija pokušati poslati ako ne uspije prvi put var sender = new gcm.Sender(gcmApiKey); // pošiljatelj var message = new gcm.Message(); // nova poruka message.addData('title', 'Naslov'); message.addData('message', "Sadržaj push notifikacije"); message.addData('sound', 'default'); message.collapseKey = 'Testing Push'; // grupa push notifikacija message.delayWhileIdle = true; //odgoditi slanje push notifikacije ako je uređaj offline message.timeToLive = 3; //broj sekundi koliko push notifikaciju držati na serveru ako je uređaj offline device_tokens[0] = "cscMv3QlzAA:APA91bFU8OQRe1Dkja-Oq3krC1fQrMV0HU8AnjLjOhbTjqbwT4ljqt2rgMpK3gt1kpPqs-8ibELSxIY4QKN7EZvdznRoRP_oSXHW1saRxqW2AziuPJ9OK8jfwli1kIm01veCyEtkRFG9"; //jedinstveni token uređaja sender.send(message, device_tokens[0], retry_times, function (result) { console.log('Push poslan na: ' + device_tokens); res.status(200).send('Push notifikacija poslana na uređaj: ' + device_tokens); }, function (err) { res.status(500).send('Neuspješno poslana push notifikacija'); }); }); |
Ako sada pokrenemo $ node push.js i odemo na putanju http://localhost:3001/push
možemo vidjeti da je push notifikacija uspješno stigla na mobilni uređaj
Gledajući prema ovom primjeru ispada da nam svaki korisnik mobilne aplikacije treba poslati svoj jedinstveni token uređaja kako bi ga mi ručno upisali u push.js i kako bi mogli tom korisniku poslati push notifikaciju. Naravno da to nema smisla i da je ovo služilo samo za test. U produkcijskoj verziji API-ja potrebno je automatizirati čitav proces i napraviti automatsku registraciju jedinstvenog tokena, slanje tokena u bazu podataka pa će API slati push notifikacije prema svim uređajima čije tokene ima spremljene u bazu.
Nadogradnja MySQL baze
Napravit ćemo novu tablicu naziva device unutar MySQL baze u koju ćemo spremati sve tokene, a koji će u bazu biti poslani čim se mobilna aplikacija pokrene.
server.js nadogradnja
Sada ćemo nadograditi prethodno napravljen API za upload datoteka koji će odmah prilikom dodavanja novog korisnika poslati push notifikaciju o dodanom korisniku.
Pomoću naredbe $ npm install node-gcm ćemo instalirati https://www.npmjs.com/package/node-gcm i na vrh datoteke dodati:
1 2 |
var gcm = require('node-gcm'); var gcmApiKey = 'xxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxx--xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx-xx'; |
Sada kada imamo spremnu novu tablicu u bazi možemo napraviti API koji će iz mobilne aplikacije primati jedinstvene tokene.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
apiRoutes.post('/device-token', function (req, res, next) { console.log(req.body); var token = req.body.token; console.log(token); pool.getConnection(function(err, connection) { if (err) { console.error("Dogodila se greška: " + err); } var uredjaj = { dev_token: token }; connection.query('INSERT INTO device SET ?', uredjaj, function(err, rows) { if (err) { throw err; } else { var result = { success: true, detail: rows } } }); }); }) |
Sada možemo nadograditi i drugi dio API-ja koji služi za dodavanje korisnika.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
//Dodavanje korisnika apiRoutes.post('/dodajkorisnika', upload.any(),function (req, res, next) { console.log(req.body); console.log(req.files); pool.getConnection(function(err, connection) { if (err) { console.error("Dogodila se greška: " + err); } var korisnik = { k_ime: req.body.ime, k_prezime: req.body.prezime, k_slika: req.files[0].destination + "/" + req.files[0].filename, k_dokument: req.files[1].destination + "/" + req.files[1].filename }; //SELECT svih tokena i slanje push notifikacije pool.getConnection(function(err, connection) { if (err) { console.error("Dogodila se greška: " + err); } var query = "SELECT * FROM device ORDER BY iddevice ASC"; query = mysql.format(query); connection.query(query,function(err,rows){ connection.release(); if (err) { return next(err); } else { var SviTokeni = []; rows.forEach(function(a) { var jedanToken = { dev_token: a.dev_token } SviTokeni.push(jedanToken.dev_token); }); //Push var device_tokens = SviTokeni; // array jedinstvenih tokena uređaja var retry_times = 4; // broj puta koliko će se push notifikacija pokušati poslati ako ne uspije prvi put var sender = new gcm.Sender(gcmApiKey); // pošiljatelj var message = new gcm.Message(); // nova poruka message.addData('title', 'Dodan novi korisnik:'); message.addData('message', korisnik.k_ime + ' ' + korisnik.k_prezime); message.addData('sound', 'default'); message.collapseKey = 'Testing Push'; // grupa push notifikacija message.delayWhileIdle = true; //odgoditi slanje push notifikacije ako je uređaj offline message.timeToLive = 3; //broj sekundi koliko push notifikaciju držati na serveru ako je uređaj offline sender.send(message, device_tokens, retry_times, function (result) { console.log('Push poslan na: ' + device_tokens); res.status(200).send('Push notifikacija poslana na uređaj: ' + device_tokens); }, function (err) { res.status(500).send('Neuspješno poslana push notifikacija'); }); } }); }) connection.query('INSERT INTO korisnik SET ?', korisnik, function(err, rows) { if (err) { throw err; } else { res.json("Uspješno dodan korisnik!"); res.end(); } connection.release(); }); }); }) |
U ovom slučaju tijelo poruke message sastojat će se od korisnik.k_ime i korisnik.k_prezime.
Iz sljedeće se animacije vidi da smo dodali novog korisnika Tomislav Stanković.
Istovremeno s dodavanjem korisnika korisnicima mobilne aplikacije stigla je sljedeća push notifikacija.
Zaključak
I to je to! Napravili smo funkcionalan API za slanje push notifikacija. Još ostaje za napraviti iOS i Android mobilnu aplikaciju koja će automatski slati token uređaja u MySQL bazu i koja će primati push notifikacije, ali o tome će više riječi biti u nekom od sljedećih blog postova jer bi ovaj bio previše dug ako bi se htjelo sve detaljno obraditi.
Posjetite GitHub i preuzmite projekt.