Integrazione Firebase Cloud Messaging e database SQL
Tecnologie e Linguaggi per il Web - Andrea Francesco Brioschi - A.A. 2020-2021
Introduzione
SQL Notification è un servizio che permette di inviare notifiche push personalizzate utilizzando i dati contenuti in un database SQL.
Il servizio permette di integrare le funzionalità di Firebase Cloud Messaging con i dati di un database SQL, l'integrazione avviene tramite la definizione di gruppi di dispositivi.
Un gruppo di dispositivi è definito da una query sul database SQL, i campi estratti dalla query sono dette keywords e possono essere utilizzate all'interno della notifica per personalizzare il messaggio.
Il servizio SQL Notification funziona in gran parte con strumenti già in possesso all'utente, infatti ogni utente definisce un database da utilizzare e un account Firebase per l'invio delle notifiche fornendo i parametri di connessione al database e all'account Firebase Admin.
1 - Analisi dei requisiti
1.1 - Destinatari
L'idea del progetto nasce dall'esigenza dell'azienda RCA SRL di personalizzare le notifiche push inviate agli utenti dell'applicazione aziendale usando i dati contenuti in un database SQL.
All'interno dell'azienda alcuni dipendenti hanno conoscenze di SQL e si occuperanno di costruire e salvare i gruppi di dispositivi che potranno essere in seguito utilizzati da tutti gli altri dipendenti anche senza conoscere la query che li definisce.
Nonostante l'azienda destinataria sia attualmente una sola è stata inserita la registrazione di diversi account che permette di definire per ogni utente un database e account Firebase diverso, in questo modo il servizio si apre all'utilizzo con molteplici database e applicazioni.
1.2 - Aspetti Tecnologici
1.2.1 - Backend
Il Backend di SQL Notification è un server NodeJs che mette a disposizione una serie di API REST per l'interazione con il database e l'invio delle notifiche push personalizzate. Le richieste al backend devono essere autenticate tramite token che permette l'identificazione dell'utente che ha effettuato la richiesta.
Autenticazione delle richieste (Auth0)
Per l'autenticazione delle richieste il servizio si appoggia a Auth0, una piattaforma per la gestione delle identità degli utenti che implementa il protocollo OAuth 2.0.
L'autenticazione delle richieste avviene tramite token di tipo Bearer, il token viene inviato dal client al server backend che a sua volta lo utilizza per effettuare una richiesta al server Auth0 che restituisce al server del backend i dati dell'utente corrispondente al token, in questo modo nelle chiamate fra server backend e client non vengono esposti i dati di configurazione del database e di Firebase Admin.
Invio delle notifiche (Firebase Cloud Messaging)
Il servizio utilizzato per l'invio delle notifiche push è Firebase Cloud Messaging, ed è strutturato in questo modo:
-
Generatore di messaggi e target: si occupa della creazione dei messaggi creando delle triplette titolo, descrizione e token che vengono inviate al backend FCM tramite Firebase Admin SDK
-
FCM backend: legge i dati inviati dal gestore, genera i metadati del messaggio e li invia agli instradatori
-
Instradatori di messaggi specifici della piattaforma:
- Android Trasport Layer per dispositivi Android
- iOS / APNs per dispositivi iOS
- Web Push per app web
-
SDK sul dispositivo: viene visualizzata la notifica o il messaggio viene gestito in base allo stato in primo piano / in background dell'applicazione e a qualsiasi logica dell'applicazione pertinente
SQL Notification agisce da generatore di messaggi e target, infatti si occupa di costruire i messaggi utilizzando i dati contenuti nel database e li indirizza al backend FCM relativo all'utente che ha effettuato la richiesta.
Codici di Indirizzamento FCM e Gruppi di dispositivi
Ogni istanza di applicazione iOS, Android o Web configurata correttamente per l'utilizzo del servizio Firebase Cloud Messaging possiede un codice identificativo univoco che è possibile utilizzare per l'indirizzamento delle delle notifiche.
Le API di SQL Notification forniscono uno specifico endpoint per salvare i codici all'interno del proprio database SQL, che verrà utilizzato dall'applicazione mobile per salvare i token, la tabella nella quale vengono salvati deve obbligatoriamente avere un campo chiamato token e una serie di campi a scelta che devono essere utilizzati per abbinare il token a delle proprietà che permettono di identificarlo (es: codice cliente).
Un esempio di tabella contenente i token potrebbe essere la seguente:
Una volta salvati i token dei dispositivi nel database è possibile raggrupparli e collegarli ad altre tabelle dello stesso database tramite query di tipo SELECT, le query possono essere salvate associate ad un titolo e ad una descrizione dando vita a quello che viene definito gruppo di dispositivi.
La scelta di definire il gruppo tramite query è stata fatta per integrare tutti i nuovi token inseriti nel database all'interno dei gruppi creati in precedenza, così facendo infatti i dispositivi relativi ad un gruppo vengono identificati nel momento dell'invio della notifica.
Template notifica con keywords
Le notifiche inviate tramite SQL Notification sono composte da titolo e descrizione, sia il titolo che la descrizione possono essere costruiti come template utilizzando all'interno del testo i nomi dei campi estratti dalla query del gruppo seguendo la seguente sintassi: [[keyword]].
Il server backend tramite espressione regolare sostituisce le keyword con il loro valore specifico prima di inviare la notifica al dispositivo.
Pubblicazione
Le API sono state messe in produzione su un server Heroku, sul server è disponibile anche la documentazione completa.
1.2.2 - Frontend
SQL Notification fornisce anche una parte di frontend ovvero un'applicazione web con design responsive, quindi facilmente utilizzabile anche su dispositivi mobili, che consuma le API con lo scopo di fornire un'interfaccia grafica per la gestione dei gruppi e l'invio delle notifiche.
L'applicazione è stata creata come single page application utilizzando il framework Javascript Vue.js che permette di costruire interfacce secondo una configurazione MVVM (Model–view–viewmodel) e Bootstrap per definire lo stile dell'interfaccia.
L'applicazione frontend utilizza un plugin, chiamato AuthenticationWrapper, fornito da Auth0 che semplifica la gestione delle sessioni e la registrazione di nuovi utenti.
L'architettura di Vue.js si concentra sull'unione di componenti favorendo la suddivisione del codice e quindi la scalabilità dell'applicazione; è stato scelto fra gli altri framework che utilizzano approcci simili grazie alla sua rapida curva di apprendimento.
2 - Interfacce
2.1 - Struttura
L'applicazione frontend di SQL Notification è una single page app, si basa quindi su una sola pagina che viene scaricata nel momento il cui viene effettuata la prima richiesta.
Attraverso meccanismi di routing è possibile caricare dinamicamente il contenuto della pagina: i contenuti vengono caricati basandosi sul path URL attuale, questo processo avviene tramite l'interfaccia Vue-Router fornita da Vue.
L'utilizzo di questo approccio permette di superare uno degli scogli più classici delle single page app: la possibilità di linkare ogni sottopagina dell'applicazione.
I contenuti caricati all'interno del Router View vengono suddivisi in due tipologie principali: le pagine di indice / re-indirizzamento e le pagine di utilizzo principale.
2.1.1 - Pagina di indice
Le pagine di indice hanno lo scopo di introdurre l'utente ad una sottocategoria di contenuti e di rendere chiara la struttura del sito.
Queste pagine sono direttamente raggiungibili tramite click sulla barra di navigazione.
All'interno delle pagine di indice Router View viene sostituito da:
- Titolo: titolo generale che introduce il contenuto delle sottopagine
- Descrizione: introduzione sui contenuti delle sottopagine.
- Bottoni: permettono di raggiungere le sottopagine
2.1.2 - Pagina di utilizzo
Le pagine di indice dell'applicazione permettono di raggiungere le pagine di utilizzo, ovvero quelle dove effettivamente possono essere utilizzate le funzionalità dell'applicazione.
All'interno delle pagine di utilizzo Router View viene sostituito da:
- Breadcrumb: mostra il percorso di navigazione e permette all'utente di tenere traccia della sua posizione all'interno del sito e ritornare ad una delle pagine precedenti.
- Titolo: titolo specifico della pagina
- Descrizione: descrizione dello scopo della pagina e spiegazioni sul suo utilizzo.
- Main Content: All'interno di main content viene caricato il componente specifico della pagina che è sempre diverso in base allo scopo della pagina stessa.
3 - Architettura
3.1 - Diagramma dell'ordine gerarchico delle risorse
Frontend
Una single page app è composta da una singola pagina HTML.
In questo caso la pagina HTML è contenuta all'interno della directory public, si chiama index.html ed è accompagnata da un file custom.css che definisce regole di stile ulteriori a quelle che è possibile definire utilizzando le classi di Bootstrap.
All'interno di index.html il contenuto viene caricato in base al path URI attualmente attivo e questo rende possibile l'indicizzazione delle diverse interfacce.
Backend (API)
Il server Node.js utilizzato come backend dell'applicazione offre una serie di endpoint organizzati in 4 categorie:
- Tokens: gestione dei token FCM necessari per l'indirizzamento delle notifiche push al dispositivo
- Groups: gestione dei gruppi di dispositivi
- Messages: invio delle notifiche
- Users: gestione degli utenti e delle configurazioni
Al seguente link è disponibile la documentazione completa.
3.2 - Descrizione delle risorse
Frontend
3.3 - Altri diagrammi
Database
All'interno del database dell'utente sono necessarie due tabelle per il corretto funzionamento dell'applicazione, una per salvare i token FCM di indirizzamento e una per salvare i gruppi creati.
La tabella app_messaging_tokens utilizza il campo token come chiave primaria per evitare la duplicazione.
4 - Codice
Indice applicazione client
Pagina index.html dell'applicazione client, i contenuti della pagina vengono caricati dinamicamente all'interno del tag con id "app".
Personalizzazione template
Ricerca, tramite espressione regolare, all'interno di text ogni parola circondata da doppia parentesi quadra e la sostituisce con il valore corrispondente all'interno di dictionary, questo metodo viene utilizzato per la personalizzazione dei template.
Servizio di invio notifiche di gruppo
L'invio di una notifica di gruppo prevede come prima cosa l'estrazione e l'esecuzione della query del gruppo desiderato, dopo di che per ogni record risultante vengono svolte 3 operazioni:
- Salvataggio della riga attuale in una variabile chiamata dizionario
- fillKeywords: personalizzazione del titolo e del corpo della notifica tramite sostituzione delle keywords presenti con gli elementi del dizionario
- Invio della notifica
Middleware per l'inserimento dei metadati Auth0 nella richiesta
Prima della valutazione di ogni richiesta vengono richiesti al server Auth0 i metadati relativi all'utente che ha effettuato la richiesta alle API (lo stesso token di autenticazione fornito nella richiesta alle API viene utilizzato per effettuare la richiesta al server Auth0), all'interno dei metadati è presente la configurazione del database e la chiave di firebase per accedere a Firebase Admin SDK.
User metadata
Rappresenta la configurazione essenziale di un utente, contiene i parametri di connessione al database e a Firebase.
5 - Conclusioni
Il progetto è stato completato con successo ed è funzionante, sono stati effettuati diversi test di funzionamento e sia le API che l'applicazione Client rispondono correttamente.
Risulta necessaria una fase di testing ulteriore con diverse applicazioni Firebase e diversi database per confermare il corretto funzionamento in caso di un grosso numero di accessi in contemporanea, in qualunque caso il servizio utilizzato per mettere in produzione le API, Heroku, applica un meccanismo di autoscaling che dovrebbe permettere di coprire tutte le richieste senza problemi.
I dubbi rimanenti sul progetto dipendono unicamente da informazioni non fornite dai servizi utilizzati, in particolare non è chiaro se sia presente un limite di account Firebase Admin configurabili in un singolo server.
L'applicazione client è stata compilata tramite vue-cli come applicazione statica (ottimizzata e minimizzata) e messa anch'essa in produzione su un server Heroku. L'applicazione client e le API risiedono su due server diversi poiché l'applicazione client è sono uno dei modi attraverso il quale è possibile accedere al servizio e non è necessariamente il modo in cui verrà utilizzata principalmente, ho scelto quindi di mantenerle distinte.
SERVER API
https://push-api.herokuapp.com/
DEFINIZIONE API SECONDO LA SPECIFICA OpenAPI
https://push-api.herokuapp.com/openapi.json
APPLICAZIONE CLIENT
https://push-notification-app.herokuapp.com/
6 - Nota bibliografica e sitografica
- https://vuejs.org/
- https://012.vuejs.org/guide/
- https://firebase.google.com/docs/cloud-messaging
- https://auth0.com/docs/
- https://auth0.com/docs/quickstart/spa/vuejs
- https://getbootstrap.com/docs/4.1/getting-started/introduction/
SQL Notification - Andrea Francesco Brioschi