HUMAN CODE – CAPITOLO 6: Matteo Sist

La curiosità è il motore che ha spinto verso il successo Matteo Sist, Mobile Tech Lead e specialista Couchbase di MOLO17.

Classe ’91, Matteo è tra i primi a far parte del team ed è anche l’amministratore della società MobileBridge.

Matteo Sist in MOLO17 - Ph Marco Cosatto
Matteo Sist – Ph Marco Cosatto

Ho iniziato 5 anni fa, quando la società si chiamava AD Solutions ed eravamo nella vecchia sede. Quando ho iniziato con Daniele eravamo in tre: c’ero io, Daniele Angeli e un altro collega. Su questo incontro, ad ogni modo, c’è un piccolo aneddoto, che vale la pena raccontare.

Andiamo però un passo per volta e torniamo indietro di qualche anno.

Le origini di Matteo Sist

Ho scelto di fare il liceo scientifico al Don Bosco, dopo le scuole medie, perché nonostante mi fosse sempre piaciuta la tecnologia, non avevo ancora le idee ben chiare su quello che avrei fatto.

Matteo è uno studente un po’ pigro, anche se i professori vedono in lui forti potenzialità.

In matematica e fisica ero molto bravo, perché se una materia mi piaceva e mi prendeva, mi applicavo, altrimenti lasciavo correre. Nelle materie umanistiche infatti ero un disastro!

Ad ogni modo il percorso intrapreso gli consente di ottenere una buona preparazione scolastica, che gli permette di trovarsi molto bene all’inizio dell’università.

L’università

Dopo le superiori ho puntato subito alla facoltà di informatica: durante il liceo, ho chiarito quello che volevo fare in futuro, la programmazione è quello che mi ispirava veramente.
Questo interesse l’ho avuto da sempre: ho iniziato ad usare il computer a quattro anni, un vecchio Windows ’95 che aveva portato a casa mia madre dall’ufficio.
La tecnologia è una delle mie due passioni. Con gli anni mi è sembrato naturale proseguire per questa strada e nel 2011 mi sono iscritto ad informatica all’Università di Udine.

Matteo segue le lezioni per circa due anni, le aspettative però vengono deluse. Tanta matematica, tanta teoria, non fa per lui.

Mi aspettavo di iniziare a programmare e vedere aspetti approfonditi di informatica, invece ho studiato per quasi tutto il tempo matematica. Tra l’altro c’era poco di nuovo rispetto a quello che avevo fatto alle superiori. Quel poco di informatica che ho studiato, era solo teoria, però non mi prendeva abbastanza. A metà del secondo anno, non avendo stimoli, ho deciso di lasciare l’università.

La svolta

Per fortuna, dalla mia ragazza, ho saputo delle giornate di Punto di Incontro delle scuole alla Fiera di Pordenone, dove c’era anche una scuola per programmatori e sviluppatori di applicazioni mobile. Ho deciso di andarci: al massimo, ho pensato, avrei perso una mattinata per niente.
Tra gli stand, ho trovato invece il banchetto dell’ITS Kennedy e avevano un programma del corso biennale TSAIM (Tecnico superiore per le applicazioni integrate su dispositivi mobili). Leggendolo, mi sono detto: “Cavolo, fanno proprio quello che mi aspettavo facessero all’università!”.

Corso TSAIM all’ITS Kennedy

Dopo essersi informato un attimo, durante la fine dell’anno del 2013, con un po’ di ritardo, Matteo si iscrive e inizia il corso all’ITS Kennedy.

Il corso era improntato sulla pratica, essendo fatto e pensato per preparare gli studenti al lavoro. I docenti erano professionisti, non professori di ruolo ma sviluppatori, quindi quello che ti insegnavano era effettivamente quello che poi ho fatto in azienda. Durante questi due anni ho anche conosciuto Damiano Giusti, che ho poi ritrovato, qualche tempo dopo, in MOLO17.

Gli stage

Il corso prevedeva due stage: il primo l’ho fatto in un’azienda di Polcenigo, anche il secondo pensavo di svolgerlo lì, ma non è stato possibile. Ho fatto due colloqui con altre aziende, ma sono stati deludenti e non mi sono trovato bene.

Una sera però è arrivata la rivelazione:

Con un mio caro amico una sera sono andato ad un pub a Pordenone. Entriamo e lui inizia a parlare con una persona, io ero in disparte. Ad un certo punto mi dice: “Vieni che ti presento una persona. Sai Daniele, quello che ha aperto la sua azienda che fa applicazioni mobile…”.
Insomma, mi ha presentato Daniele Angeli. Guarda caso è venuto fuori che io cercavo un’azienda dove poter svolgere lo stage e lui cercava un collaboratore per la parte Android.

Matteo Sist e lo stage in AD Solutions

Dopo quella sera Matteo e Daniele si scambiano i contatti e, si può dire, da quel momento non si sono più lasciati. Matteo intanto svolge lo stage all’AD Solutions, che si è appena trasferita nel 2014 a Zoppola, ma continua a collaborare nel tempo libero anche in seguito, in contemporanea con le lezione del corso. Subito dopo il diploma Matteo viene assunto a tempo pieno in azienda e così inizia ufficialmente la sua carriera professionale.

Settore Mobile

Perché ti sei specializzato nell’ambito mobile?

All’epoca gli smartphone mi ispiravano, sembravano qualcosa di nuovo, erano una novità cinque – sei anni fa. Ora li hanno tutti, ma allora no. Essendo una cosa informatica, nuova, con un buon sviluppo in futuro, ho deciso per questo ambito. Mi sono indirizzato verso l’Android perché l’ITS faceva principalmente corsi Android, iOS in modo solo marginale. Di quest’ultimo quello che ho imparato l’ho appreso con Daniele, che mi ha fatto da tutor per tutta la parte di programmazione iOS.

Couchbase

Logo Couchbase
Logo Couchbase

Sono stato il primo, assieme a Daniele, a conoscere ed approfondire Couchbase. Couchbase è un database che ha un motore di sincronizzazione unico nel suo genere tra mobile e backend. 
Abbiamo fatto un’applicazione mobile, una to do list, che permettesse di sincronizzare i dati tra un Android e un iPhone. Ai tempi era una cosa davvero incredibile, nessuno ce l’aveva!

App Connection

Grazie a Couchbase, si aprono una marea di possibilità di utilizzo e iniziano le prime sperimentazioni sul campo. La prima tra tutte, una di quelle con più di successo, è l’applicazione creata per Connection, uno tra i primi clienti di MOLO17.

Abbiamo iniziato ad approfondire Couchbase ancora di più, a capire come integrarlo su altri progetti. Alla fine, è stato uno degli sviluppi più promettenti. Una delle prime sperimentazioni di Couchbase lo abbiamo fatto con Connection, in quel periodo c’era l’esigenza di rifare l’applicazione mobile che avevano, perché non era stata aggiornata e ormai risultava datata.
Il primo progetto, vero e proprio, è stato proprio l’app di Connection, ed è stato anche uno dei primi utilizzi reali di Couchbase. Quest’anno è stata rifatta l’applicazione perché hanno fatto un cambio di gestionale, e quindi avevano la necessità sia di rinnovarla, sia per ristrutturarla per agganciarsi al nuovo gestionale. In questa applicazione ho potuto applicare tutte le competenze che ho acquisito in questi anni, se 4 anni fa ero molto soddisfatto di questa applicazione, oggi lo sono ancora di più!

2019 - Matteo con Daniele Angeli di MOLO17 e Roberto Zuccaro di Connection al 20° anniversario di Connection
2019 – Matteo con Daniele Angeli e Roberto Zuccaro al 20° anniversario di Connection

La suite MobileBridge

Grazie a questo progetto nasce una nuova idea, stella nascente di quello che sarà un nuovo inizio.

Dalle sperimentazioni, ho avuto un’intuizione per risolvere questo problema: ho un database che mi sincronizza tutti i dati tra i dispositivi mobile, i miei dati però non sono su Couchbase, sono su un SQL server, un database del gestionale. Come dunque portare i dati dal gestionale su Couchbase, facendoli comunicare tra loro? Da qui è nata l’idea di MobileBridge.
Dopo ricerche e studi, io e Daniele abbiamo sviluppato questa applicazione, in realtà erano due, una in lettura e una in scrittura. MobileBridge è un motore di sincronizzazione che fa comunicare due database, completamente diversi tra loro; prende i dati da un database, li converte e li riscrive per l’altro database.

Leads Collector

App Leads Collector sviluppata da MOLO17
Leads Collector

Da Couchbase quindi sono nati due grandi progetti: uno è MobileBridge, un applicativo lato server, il secondo è Leads Collector, progetto interno del 2015, che è stato pubblicato e poi venduto a livello internazionale.

Leads Collector è, per dirla in modo banale, un’applicazione per raccogliere contatti. Alla base c’è l’intuizione di creare un’applicazione per raccogliere i contatti, ad esempio durante le fiere, che si adattasse allo specifico utilizzo, per avere quindi anche specifiche informazioni grazie alla possibilità di customizzare il form di raccolta dati. Ogni cliente può personalizzare l’applicazione in modo da avere tutte le informazioni di interesse e che gli permettano di classificare il pubblico, per indagini di mercato in base al tipo di risposte, ad esempio. Questa applicazione utilizza Couchbase.
Con la versione business è possibile anche lavorare in team, per vedere i grafici di performance del team e conoscere anche chi raccoglie più contatti o il prodotto più venduto.
Leads Collector è stata pubblicata sullo Store e ha avuto un discreto successo. È stata scarica sempre da più persone e sempre più da clienti importanti, come Lego.

L’arrivo “ufficiale” di Matteo Sist in MOLO17

Intanto è nata, a fine 2015, MOLO17 e Matteo Sist partecipa anche al progetto Dubai. Quasi tutta l’azienda si concentra in questo progetto, che lo vede tra i protagonisti principali.

Progetto Dubai

Ci sono solo pro per questo progetto. Già dall’inizio è considerato come una grandissima sfida, fino a quel momento avevo affrontato piccoli progetti, ma non avevo mai avuto l’occasione di lavorare per un progetto così importante e un team così grande di persone. In più, ho avuto la fortuna di poter andare a lavorare a Dubai e di lavorare vicino a professionisti che lavoravano in grandi aziende estere, che mi ha fatto crescere tantissimo. Il pro è stato senza dubbio la crescita. Nel giro di poco tempo, sia per me, sia per i miei colleghi (Daniele Angeli, Damiano Giusti, Francesco Furlan) abbiamo imparato tantissimo.

Matteo nel deserto di Dubai durante un importante progetto di MOLO17
Matteo nel deserto di Dubai

Progetto gruppo bancario europeo

Rientrati dal progetto Dubai, Matteo e il suo team hanno lavorato e stanno lavorando sul progetto di un grossissimo gruppo bancario europeo.

Abbiamo sviluppato una corporate chat per i dipendenti per comunicare tra loro: al progetto poi si è aggiunto lo sviluppo di un CRM che abbiamo portato sul mobile, utile per consultare i dati anche al di fuori della sede di lavoro, in mobilità.

Corso Couchbase

Certificato di completamento corso Couchbase CS300 NoSQL Server Administrator sponsorizzato da MOLO17
Attestato Couchbase NoSQL Server Administration, 4-Day

La formazione continua: Matteo Sist nel 2017 partecipa al corso Couchbase CS300 Couchbase NoSQL Server Administration, 4-Day. 4 giorni di corso dedicati alla parte di server administration. 

MobileBridge Srl e Matteo Sist

Logo MobileBridge
Logo MobileBridge

Nel 2018 nasce la società di MobileBridge. Come? Matteo lo racconta così:

Circa un anno e mezzo fa, uscendo a cena, Daniele mi ha proposto di prendere l’applicazione di MobileBridge, sviluppata insieme, e fondare un’azienda, diventando suo socio. Io ero sorpreso, è stata una proposta che non si vede tutti i giorni, e ho accettato. Per me era un orgoglio che il mio titolare mi dicesse, comunque dopo aver creato e sviluppato un prodotto assieme, di farne una società.

Dopo qualche mese, Matteo Sist diventa l’amministratore delegato della neo-nata MobileBridge Srl. Oggi la società si sta evolvendo: è un’azienda di prodotti, non più solo un’app.

Dall’idea del progetto di stage e le esigenze operative è nato un prodotto che poi si è evoluto in progetto di sviluppo, come prodotto di suite della società, che porta lo stesso nome dell’applicazione.

Matteo Sist: oggi Tech Lead Mobile in MOLO17

Matteo Sist in MOLO17
Matteo Sist in MOLO17

Che ruolo hai assunto oggi in MOLO17?

Sono Tech Lead Mobile in MOLO17, ho iniziato come sviluppatore Android, sono cresciuto come figura di riferimento per tutto il team di sviluppo, per la gestione e scelte da adottare. Sono la persona che si occupa del mondo Mobile dell’azienda, anche perché ho le competenze in entrambe le piattaforme Android e iOS. Non decido cosa fare, sono una persona che raccoglie le esperienze di ciascun membro del team e le mette assieme. Anche quando si avvia un nuovo progetto, voglio che si scelgano insieme le proposte e strategie più adatte e utili per procedere. La mia figura è chiave in azienda, è una bella posizione perché mi dà la possibilità di poter svolgere ricerca e sviluppo e sperimentare, ma dall’altra parte è una bella responsabilità.

La scommessa su Kotlin

Un esempio fra tutti è la scommessa sull’adozione del neonato linguaggio Kotlin: io e Damiano Giusti abbiamo deciso di seguire un corso Kotlin in azienda tenuto da uno dei massimi esponenti al tempo residente in Francia. Allora vedevo già una grande potenzialità ed usabilità di questa tecnologia. Mi è piaciuto fin da subito il linguaggio, ho visto qualcosa di nuovo e diverso da Java. Lo ammetto, è stato un azzardo, una scommessa che è stata largamente ripagata però, perché ora usiamo Kotlin ovunque. Ci ha permesso di compiere un salto di qualità, anche per le performance.

Docente in ambito Mobile

Durante la sua carriera, Matteo Sist ha ricoperto anche il ruolo di docente e ha tenuto diversi corsi in ambito Mobile. Dal 2016 ha seguito questi percorsi formativi:

  • “SVILUPPARE APPLICAZIONI PER ANDROID” presso lo IAL (marzo 2016);
  • Corso base per lo sviluppo di applicazioni Android presso BuildingApp (maggio 2017);
  • Corso base per lo sviluppo di applicazioni Android presso Logika Software (febbraio 2017);
  • “TECNICO SUPERIORE PER I METODI E LE TECNOLOGIE
    PER LO SVILUPPO DEI SISTEMI SOFTWARE”, moduli “Project work” e “Gestione progettuali” presso ITS Kennedy (giugno-luglio 2019).

Oltre MOLO17

Matte Sist è curioso, molto curioso.

La curiosità mi ha dato la possibilità di essere dove sono. Sono paziente, anche se non sembra. Sono anche riservato, forse schivo. Mi definirei il classico motociclista solitario.

Matteo Sist, in realtà, non ha due, ma ben tre passioni. Una, molto divertente, sono i dinosauri. Basti pensare che, come immagine di profilo di tutti i suoi account, da anni, ha un avatar di un T-Rex verde stilizzato.

T-Rex, l'avatar di Matteo Sist
T-Rex

È il mio avatar storico, ci sono affezionato. Da piccolo, e anche tuttora, i dinosauri sono una mia grande passione, come per tutti i bambini. Trovami un bambino che non è innamorato dei dinosauri.

Moto e motori, le passioni di Matteo Sist

L’altra passione, oltre la tecnologia, sono i motori. Gli occhi gli brillano solo a nominare la parola moto.

Matteo Sist e la sue passioni: moto e tecnologia
Matteo e la sua moto oggi

La passione mi è stata trasmessa da mio papà, da bambino guardavo le gare della F1 assieme a lui. Da piccolo sei affascinato dai motori, poi, quando diventi più grande il fascino diventa passione.

La prima – Fantic Caballero 50cc del 1972

Fantic Caballero 50cc del 1972

È iniziato tutto con la moto di mio papà, avevamo e abbiamo a casa un vecchio Caballero del ’72, è la sua moto da quando aveva 14 anni. Ai miei compagni di classe, quando avevano 14 anni gli veniva comprato il motorino, io invece ho preferito aspettare i 16 anni per prendere un 125. Nel frattempo, abbiamo restaurato in parte la moto di mio papà: l’abbiamo smontata, pulita e sistemata e ho imparato a guidare con questa. Correvo sui terreni dell’azienda agricola di famiglia e faceva un rumore assurdo, la moto era completamente elaborata, non potevo andare per strada. Ai tempi non esistevano neanche le targhe per i cinquantini. È una moto storica, oggi si potrebbe riutilizzare, ma dovrebbe essere restaurata di nuovo ed essere immatricolata.
Questa comunque è stata la mia prima moto, insieme al motorino di mia nonna.

La seconda – Husqvarna SM 125 del 2007

Husqvarna SM 125 del 2007 di Matteo Sist
Husqvarna SM 125 del 2007

Arrivati i 16 anni, ho avuto la fortuna grazie ai miei genitori, di avere una moto più seria, una 125. Ho preso la patente prima che potevo: compio gli anni a gennaio, un mese dopo ce l’avevo in tasca.
Avere una moto è stata una liberazione, averla mi dava l’indipendenza, mi sentivo libero.

La terza – Aprilia Shiver 750 del 2009

Aprilia Shiver 750 del 2009 di Matteo Sist
Aprilia Shiver 750 del 2009

A 18 anni Matteo prende la patente A2, sempre grazie ai suoi genitori, e acquista una Aprilia.

L’ho tenuta una decina d’anni, l’ho ceduta a mio fratello solo quest’anno.

La quarta – Yamaha WRF 250 del 2004

Usata, ma non da dimenticare, Matteo Sist ha avuto anche una moto da cross. Si diverte a correre sullo sterrato e partecipa anche ad una gara amatoriale.

Il mio sogno è sempre stato quello di fare il pilota, ma ovviamente c’è lo 0,5% delle probabilità di diventarlo sul serio. Ad ogni modo sono riuscito a partecipare ad una gara amatoriale e, l’importante, non sono arrivato ultimo. Avevo la moto, il casco e mio fratello ad aiutarmi. La sfortuna è stata che ha piovuto la sera prima e c’era fango ovunque. La mia moto non era preparata. Il mio obiettivo era quindi quello di non farmi male e di non arrivare ultimo. Un successo allora in tutti e due i casi!

La moto dei sogni – Aprilia Tuono V4 Factory del 2018

Matteo Sist e la sua Aprilia Tuono V4 Factory del 2018
Matteo e la sua Aprilia Tuono V4 Factory del 2018

Purtroppo, con i mille impegni, Matteo Sist usa poco la moto oggi, o almeno non quanto vorrebbe. Se fosse per lui, mi confessa, che sarebbe sempre in moto.
Ora ne ha anche una nuova di zecca che lo attende:

Mi sono detto ora o mai più e mi sono comprato la moto dei miei sogni: una Aprilia Tuono V4 Factory del 2018. Quella che quando ero alle superiori mi potevo solo sognare, che ho desiderato tanto. Alla fine ho realizzato il mio sogno dell’adolescenza. 

Matteo Sist tra cinque anni

E tra 5 anni quindi come ti vedi?

Non lo so. L’idea che ho è che quando metterò famiglia voglio vendere la moto, perché oggettivamente è un pericolo. Magari tra cinque avrò una casa tutta mia, ora sono in affitto, un appartamento non fa per me. Non si sa mai, magari avrò un figlio.

A livello lavorativo vorrei continuare a crescere, sia a livello di esperienza, sia di ruolo, per quanto riguarda MOLO17. Per quanto riguarda MobileBridge, mi piacerebbe fosse come MOLO17 oggi, dopo quasi 5 anni. Tra cinque anni MOLO17 magari avrà 100 dipendenti, mentre MobileBridge ne avrà 20. Potrebbe essere un buon augurio.

Conclusione

Per terminare, Matteo rivolge un grazie particolare a queste persone importanti:

Ringrazio la mia famiglia perché mi ha fatto diventare quello che sono, mi ha dato dei valori che per me sono fondamentali. Grazie a Romina, la mia ragazza, il mio braccio destro, anzi la mia metà, che mi ha sempre sostenuto e supportato in tutti questi anni. Ringrazio anche Daniele, grazie a quell’incontro casuale al Metrò che mi ha aperto questa opportunità lavorativa.
Oggi sono soddisfatto del ruolo professionale che ricopro, faccio quello che mi piace. Poi vado anche a lavoro in moto, quando non piove. Meglio di così!

Matteo Sist e Daniele Angeli, anno 2019 - Premiazioni concorso interno MOLO17 Knowledge Route
2019 – Premiazioni concorso interno MOLO17 Knowledge Route

Grazie per l’ironia Matteo 🙂

Al prossimo articolo di Human Code. Chi sarà il settimo marinaio di MOLO17 ad essere intervistato?

Per leggere la serie clicca qui.

A presto

How I built a Slack bot for our lunch break

We all know, developers are known to be lazy people. I’m a developer, but I honestly don’t appeal myself as lazy as people judge the average developer. I like to optimize and automate repetitive tasks, and this involves always some hacky stuff I must do to accomplish my goal. That being said, I want you to know that the story I’m going to tell you is not about laziness… it’s about optimization ? and Slack bots ?

The lunch time in MOLO17

At MOLO17, every day from 1PM to 2PM we enjoy the lunch break. We are used to go to a pub in a town near our office. It offers a casual setting, a good choice of courses and the owner is a crazy nice person. A great place to enjoy a meal with all the team!

Every day the pub’s menu changes with different courses. And on a daily basis, the owner – let’s call him Bob – always shares on Facebook and WhatsApp a picture of a blackboard in which he writes down the menu. In this way, the customers will know what kind of courses will be served for lunch.

What made me think we needed a Slack bot for lunchtime

Every day, I opened his Facebook diary and posted the daily menu into our dedicated Slack channel (yes, we have even a #lunch channel).

Blackboard of meals available as daily menu at the Restaurant for lunch time: This is what we're going to grab from our slack bot
The blackboard Bob uses for the daily menu. Yum!

And here comes my laziness optimization-ness. The main “problem” of this process was that I had to manually check every day, starting from 11AM, if Bob uploaded the menu on his Facebook diary. Since checking other’s Facebook page is not my job, I started a funny weekend project for automating this stuff.

Requirements for my Slack Bot

What I needed was a Slack bot. Such bot would have checked one of the Bob’s social pages, and if it had found some new menu pictures, it would have posted them inside our #lunch Slack channel. Moreover, the process would have been triggered every 5 minutes, between 11AM and 1PM. In fact, this is the time interval in which Bob usually uploads the blackboard pics.

Quick feasibility studies

Bob uploads the menu pictures on his Facebook diary, and often on his WhatsApp status. Hence, I explored how to integrate with one of these systems for getting the freshly uploaded picture.

Obviously, I chose Kotlin as language for letting my idea come to life.

WhatsApp APIs

I decided to start with WhatsApp. Although I knew that such company doesn’t expose a public API, I wanted to explore a bit its implementation. At least I would have learnt something new!

I started checking out how WhatsApp works under the hood. I found an interesting and well documented project about a reverse engineering of its chat protocol. Therefore, I started implementing my own version.

After an intensive Sunday afternoon, I was able to connect to the WebSocket that WhatsApp exposes and to log in by rendering a QR code given a payload (as the Web version does), that I subsequently scanned with my mobile phone. It was a but painful, due to the RSA keys manipulation that the WhatsApp client performs. Once logged in, I got the ID and the name of some chats, just for testing purposes.

Investigating more on the WebSocket events received when opening the user status page, I ended up by just throwing away the idea of using this mean for getting the pictures. All the media that WhatsApp shares are (obviously) encrypted, and I would have needed to apply other alterations to the handshaked key pair for decrypting them.

This stuff would have required me a lot of effort. Instead, I wanted something simpler and easier to maintain as weekend project. Hence, I moved my focus to Facebook.

Facebook Graph APIs

Facebook exposes certain data under a public API, called Graph API. This API can be accessed using a token obtained after performing a login with a set of predefined UI components. Integrating such components inside a mobile app or a web app is pretty simple. However, my need was to perform an authentication without a user interface, which is seems that isn’t directly possible.

Thus, I chose to read Facebook data by scraping them directly from the HTML code. I used a helpful tool called SeleniumHQ, used for web pages automation and testing. It’s a server which comes with a bunch of drivers written in almost all of the most popular languages. The Java version was my way to go.

A bit of structure

A software using the Selenium driver needs a Selenium server up and running. Hence, I looked for a Docker image to setup my instance quickly and without worrying too much about infrastructure. In particular, I chose the StandaloneChrome image.

Docker

I wrote down some ideas on how to organize my Slack bot, and I came up by choosing Docker Compose to orchestrate 3 containers, each one serving a specific scope:

  • selenium: obviously, an instance of the SeleniumHQ server. It exposes the port 4444 for allowing drivers to connect;
  • lunch-bot: a rest server written in Kotlin that exposes an endpoint for checking the Facebook page looking for the blackboard pictures. It exposes the port 8080 for accepting requests;
  • cron: a simple Alpine Linux container which executes an HTTP GET call to the lunch-bot. Such call is scheduled by a cron job to run every weekday from 11AM to 1PM.

Slack’s Incoming Webhooks for my Bot

For interacting with Slack, I read about Incoming Webhooks. They are a simple API which allows us to post messages and more into a Slack channel, just by performing an HTTP POST request.

We can configure a Webhook to post to a specific channel of a specific workspace, and for each Webhook set up Slack makes available a different URL, used for the POST request.

Firebase Remote Config

For getting Bob’s pictures, Facebook obviously requires a logged-in browsing session. Hence, the most immediate way to get a valid one was to inject my credentials in the HTML code using SeleniumHQ, and then submitting the form.

This solution will have worked, however it will have required me to deploy again my Kotlin application only for changing the Facebook credentials.

Firebase to the rescue!

I setup an application project on the Firebase Dev Console and enabled the Remote Config feature. In such way the Slack Bot can retrieve the credentials on each run, and I will be able to swap them at any time if needed.

In addition, I implemented a pretty dumb encryption method, just to not store a plaintext password as remote config.

With this setup in mind, I started writing the bot.

The lunch Slack bot

The Slack bot is a Kotlin REST server, written using Ktor. It exposes a single endpoint, which accepts an HTTP GET request.

Little architecture

The architecture is pretty simple. There is a main layer which contains the logic that the Slack Bot needs to accomplish my requirements.

Then, there is a storage layer used for persisting some values, like the last run timestamp and the identifier of the last obtained picture. Such layer is an abstraction, hence I can rewrite my implementation by using a proper database, if I’ll really need to (I’m using plain text files at the moment ¯\_(ツ)_/¯).

Finally, I made a small networking layer used for the Slack communication, just to be clean.

I setup the Ktor server on the main method, together with all the class hierarchy.

PS: I always apply Inversion of Control. Apart from the benefits you get when testing, I consider it a cleaner way to write code, decoupling classes instantiation from instance usages. Honestly, you should use it too, even for simple projects!

Quick overview

The REST call entry point is represented by a suspending lambda thanks to Ktor. When the GET handler is invoked, the execution flow passes to the LunchBot class, which contains the logic we need to apply.

embeddedServer(Netty, port = 8080) {
  install(AutoHeadResponse)
  routing {
    get {
      val result = bot.start(this)
      ...
    }
  }
}.start(true)

The Bot uses a Configuration class for fetching the Facebook credentials from Firebase Remote Config.

Then, the Bot gets from the storage layer the last execution timestamp. Such timestamp is stored only if the run obtains valid results. Also, if the last successful run completed on the current day, the execution is skipped.

Grabbing pictures from Facebook APIs with the Bot

After that, the Slack Bot uses a FacebookFacade class, which wraps all the operations that are performed using SeleniumHQ. With such class, it performs a login with the given credentials by injecting them into the text inputs of the HTML page and submitting the form.

For scraping the data, I use the mobile version of Facebook instead of the desktop one, mainly for two reasons. First, the desktop version contains plenty of Javascript magic: for a reliable parsing, is not the way to go. Also, Facebook has a mechanism for recognizing user’s browsing behavior. Thus, it can determine whether a visitor is a bot instead of a real person, blocking then all the network traffic. After some research I found this blog post where the author had the same problem I experienced (God bless the internet), and following his suggestion I changed the implementation using the mobile website.

Finally, the Bot lands into the Bob’s pictures page. It relies on the chronological sort made by Facebook when displaying the photos, from the most recent to the last. In this way, I can state that if a picture appears before the last obtained one, then the photo must be a new one. Also, an image is discarded if was not uploaded during the current day.

From the pictures HTML, the Slack Bot extracts the Facebook internal URI (like https://scontent-mrs2-1.xx.fbcdn.net/..), and posts it to Slack using the networking layer.

Conclusions: what can be improved in my Slack Bot?

This weekend project allowed me to master a lot concepts. I grew up my knowledge about building a REST server, that Ktor makes very straight-forward. Also, I sharpened by Docker skills. How cool is Docker? I’m not dubious on the fact that it has become a standard. Even mobile app developers like me can get servers up and running in no time.

As an improvement, I could use AutoML (the brand new Google‘s machine learning as-a-service platform) for filtering out pictures that does not contain something recognized as a blackboard. But man, it sounds a bit overkill ?

I hope you got some inspirations for building something similar by your own! Thanks for reading!

Stay tuned: @damianogiustimolo17.com

Combined use of Firebase Authentication and Firebase Cloud Firestore in Android – Part 2

As done in the first part, I’ve a question for you! ? There are a lot of possibilities to implement an Android app with database features, but what do you think if I told you that there’s a method with which you can add a database syncable across all the platform and also handle data from a web page? Yes, you’re right… Google and Firebase with Cloud Firestore! ?

I’m talking about Firebase Cloud Firestore. Cloud Firestore is a flexible, scalable NoSQL cloud database with the capabilities to sync data across all attached platform. In addition offer offline support both for mobile and for web that work regardless of network latency or Internet connectivity.

The Cloud Firestore data model supports flexible, hierarchical data structures. Store your data in documents, organized into collections. Documents support many different data types, from simple strings and numbers, to complex, nested objects and subcollections.

Tip: If you are totally new in non-relational database model, suggest you to give a look to the official Firebase Cloud Firestore documentation regarding the database model.

Querying is expressive, efficient, and flexible. You can retrieve data at the document level without needing to retrieve the entire collection, or any nested subcollections.

In this second part you will learn how to read/write the role of an employee from Cloud Firestore in your Android app.

Enable Firebase Cloud Firestore

In order to enable Cloud Firestore open the Firebase Console and select the project created in the first part of the tutorial.

Cloud Firestore Database creation

Now click on Database section and you will see the top of the page like this:

Firebase Cloud Firestore initial banner: create a database
Cloud Firestore – Create a database

Then click on Create Database.

You can now choose if you want to keep the database public or set usage rules, those rules are editable in a second time. Choose Start in locked mode, click on Enable and start inserting data in your database clicking on Add collection.

Set the Firestore collection ID

Firebase will present you a mask like:

Firebase Cloud Firestore start a collection dialog: Set collection ID
Start a collection dialog: Set collection ID

The Collection ID is the main collection name (like table name in SQL database) then in our case we can insert roles.

Add the first document to Cloud Firestore

After the Collection ID you have to insert the Document ID. This will be the name of the role (e.g. administrator), then insert the role name in the Document ID box. Finally, as you can see in the picture below, it’s already possible to insert Document data using Field.

Firebase Cloud Firestore start a collection dialog: Add first document
Start a collection dialog: Add first document

In Field box insert users and select array as field type, finally insert all the UIDs you want for administrator role and once finished click on save.

If you want insert some other roles you have to click on Add document in the roles column and then start adding the users list as described above.

The final structure that will be obtained is similar to this:

Firebase Cloud Firestore start a collection dialog: database overview
Firebase Cloud Firestore database overview

Improve security to your Cloud Firestore database

Tip: To improve security of your database go to the Rules tab. In our example, we want to allow read/write to authenticated user then we have to use these security rules:

allow read: if request.auth.uid != null;
allow write: if request.auth.uid != null;

Like in the image above.

Great you’re ready to use Cloud Firestore in your Android app! Hurray! ?

Coding Time ?

First thing to do is add the Cloud Firestore dependency to Gradle with

implementation 'com.google.firebase:firebase-firestore:18.0.1' 

then Sync Gradle and get ready to code! ?

Let’s start from read operation!

In the previous part we’ve implemented the MainActivity that we will use to retrieve and show the role of the employee. We can create a method getUserRoleWithQuery which will retrieve data from Firebase Cloud Firestore using Cloud Firestore Queries.

First of all you can add to the BaseActivity a variable used to access the current user info for example the UID, like:

protected val currentUser: FirebaseUser?
    get() = auth.currentUser

Then in your MainActivity add the method getUserRoleWithQuery:

currentUser?.uid?.let { uid ->
   firestore
       .collection("roles")
       .whereArrayContains("users", uid)
       .get()
       .addOnCompleteListener { task ->
           task.result?.run {
               when (documents.size) {
                   1 -> {
                       val role  = documents[0].reference.path.split("/")[1]
                       user_role_text_view.text = "Your role is: $role"
                   }
                   else -> showError()
               }
           }
       }
       .addOnFailureListener { showError() }
} ?: showError()

Notes

  • firestore is an instance of FirebaseFirestore (FirebaseFirestore.getInstance()).
  • Method collection identify where to query for data.
  • Method whereArrayContains query for an array which contains a specific value (for example search in “users” array our users UID).
  • documents[0].reference.path identify the role path (for example roles/administrator) so we split this path to get only the role name.
  • We’re asserting that a user can assume only a role so if documents size is greater than one, something went wrong with the call or the currentUser is null i show an error.

Let’s finish with write operation!

Now your app can read the role from your database populated from Firebase Web page. However, why stop here if you can handle also the creation of a new user/role in your database directly from your app?

Before all you have to add three extensions and the onComplete listener implementation (for authentication create user method) in your SignInActivity so you can handle all the new user register flow.

The first extensions i’ve added in the example is Task<Void>.addCompleteListener() used to add the complete listener for add/update user request. It’s very simple and the result of my implementation is:

private fun Task<Void>.addCompleteListener() {
   addOnCompleteListener {
       MainActivity.newInstance(this@SingInActivity).let(::startActivity)
       finish()
   }.addOnFailureListener {
       FirebaseAuth.getInstance().signOut()
       Toast.makeText(baseContext, "Error saving user", Toast.LENGTH_SHORT).show()
   }
}

User add method

The second extensions i’ve added isDocumentReference.addNewUser(uid: String) so, when a role doesn’t exist in our database, we can add it with related user. In order to add both the role and the related user you have to use the set method present in the DocumentReference class which we are extending:

private fun DocumentReference.addNewUser(uid: String) {
   val userMap = HashMap<String, MutableList<String>>()
   userMap["users"] = mutableListOf(uid)
   set(userMap).addCompleteListener()
}

The set method accept a map as params then we create an HashMap where we store the array of user for the role. As you can see in the map we store a list of uid associated to the users key used by Cloud Firestore to create and name your array populated with your list.

Users array update

Third and last extension is DocumentReference.updateArray(uid: String) used to add a new user to the users array when inserted role already exist. To do so you can use the update method of DocumentReference:

private fun DocumentReference.updateArray(uid: String) {
   update("users", FieldValue.arrayUnion(uid)).addCompleteListener()
}

In this case you will use the update method that accept the array name you want to update and type of operation you are executing. As we want to keep the users already added to our array we must use the FieldValue.arrayUnion. As a result of this operation, Cloud Firestore will add new uids in array maintaining old users uid.

Finally you have to implement your onComplete listener. Most important thing here is check if inserted role exist in your Cloud Firestore database or not and select the correct extension to call like:

currentUser?.uid?.let { uid ->
   val role = roles_edit_text.text.toString()

   firestore
       .collection("roles")
       .document(role)
       .get()
       .addOnSuccessListener { docSnapshot ->
           if (docSnapshot.exists()) {
               docSnapshot.reference.updateArray(uid)
           } else {
               docSnapshot.reference.addNewUser(uid)
           }
       }
}

Now you have all the required method to start the registration flow using FirebaseAuth.

Final Step!

Last method to use is createUserWithEmailAndPassword of FirebaseAuth that will register effectively new user on Firebase. Hence you can call this method like:

auth.createUserWithEmailAndPassword(
   email_edit_text.text.toString(),
   password_edit_text.text.toString()
).addOnCompleteListener(this)

Conclusions: Firebase Auth plus Cloud Firestore

Great, all done! You have now a fully working app with authentication and database linked together.

Our journey exploring Firebase Authentication and Cloud Firestore is now over, thanks for reading and stay tuned for more article! ?

You can find all the code in this Github repository! ?

Kotlin Native: A trip into Multiplatform Projects – Part 3 – An every day app

In the previous post of this series, we enjoyed a full immersion trip about using BLE in a Kotlin Native Multiplatform project.
We integrated a BLE device by reading an exposed characteristic which sends notifications, and delivered the updates to the user every time the characteristic changed.

Such scenario is challenging but not so common in the every day app development. Therefore I wanted to explore a better use case, like a simple rest call for fetching some users and the UI code for displaying them.

Structuring the Kotlin Native MPP

A key point of Kotlin Native MPP is the source sets organization, in order to share as much code as possible. The new kotlin-multiplaform Gradle plugin helps such intent by allowing you to define various source directories, each targeting a different platform.
You will have a commonMain source set containing all the pure Kotlin code, shared across the platforms. Then, if creating a mobile app, you can have a androidMain source set together with an iosMain set, defining the platform-specific code.

This structure introduces a clear separation of scopes, forcing the pure Kotlin module to be framework agnostic. For that reason, if you want to make out the most of this organization, you can take advantage of various design patterns to share as much logic as you can.

In addition, the powerful Kotlin Coroutines library allow you to make an abstraction over threading. Using them, you gain the advantage of writing asynchronous code in a synchronous and more readable form.

Such capabilities play very well in this multi platform context.

The project in Kotlin Native

As introduced before, our project will be a multi platform app which fetches a list of users by consuming a REST API. Once done, it shows the results to the application user as a list. Pretty common use case.

We’ll use randomuser.me, an open API which returns a list of mock users, even with a profile picture. By consuming such service, we’ll get a Json response from which we’ll keep only the data we really need. Then we’ll compose a simple UI-representable model for letting the UI code to be as simpler as we can.

Taking advantage of the mentioned multi platform source sets, we’ll try to maximize the code sharing.

Also – since we are good developers and we must keep the app responsive – we will dispatch in the background all the work that is not related to the UI. In order to do this, we will delegate the task to Kotlin Coroutines, applying the work deferral only in one point. Thus, all our code will be synchronous, but sent in the background only when executed.

“IMHO moment”: In general this idea should be applied to most of the cases in which you need to defer work in the background. Most importantly, it helps you to avoid spreading of async code, callbacks or whatever. Frameworks like RxJava help you to overcome this, but for simple projects you may don’t want to add such dependency. By the way, this is another topic!

Fetching the users

As said before, we’re going to consume the randomuser.me API for getting some users data.

Structuring sources. How?

To maximize the code sharing, will be great if we could reuse also the code which performs the HTTP call. We can follow two paths for achieving the result:

  1. Create a common interface defining our requirements, and implement an Android version (OkHttp and the Gson converter) and an iOS version (Moya and models implementing Swift Codable protocol);
  2. Create a common class using a multi platform HTTP client as Ktor client and a multi platform JSON serialization library, like the cool kotlinx.serialization provided by the Kotlin team itself.

The second point looks attractive to us, but we want to maintain the loose coupling that the first point introduces. Hence, we can still create the common interface, called UserApi. We’ll implement it in the common module using Ktor and kotlinx.serialization. We’ll write all the code to depend on the interface. Therefore, if needed, we can throw away such implementation in favor of the first solution, without changing anything. Remember the LSP and the DIP? Uncle Bob will be proud of us!

So let’s create a class called AllUsersResponseDto, defined here for brevity, and the UserApi interface, defined as:

interface UsersApi {
    suspend fun getUsers(): AllUsersResponseDto
}

It’s very simple. For now, ignore the keyword suspend, more on it will be explained later in this post.

Dependencies

The AllUsersResponseDto class will be annotated with the kotlinx.serialization.Serializable annotation, allowing the compiler to generate serializers for us.

We add the serialization Gradle plugin to the classpath dependencies of project build.gradle file. Remember that it requires a Kotlin version greater than 1.3.20.

classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"

And then we update our module’s build.gradle with the platform-specific dependencies. We need to distinguish the artifact based on the source set we target.

commonMain {
  dependencies {
    ...
    api "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion"
  }
}

androidMain {
  dependencies {
    ...
    api "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion"
  }
}

iOSMain {
  dependencies {
    ...
    api "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serializationVersion"
  }
}

Here we’re exposing the serialization lib using the api directive to other modules. If we decide to implement the UserApi interface with platform-dependent code, we’ll be free to use the kotlinx.serialization lib.

Then, as said before, we have to create the shared implementation of the UsersApi. It will use the Ktor Client library for making HTTP calls.

Import the Ktor Client library as we did previously. Moreover, we add the Ktor JsonFeature, which integrates perfectly with kotlinx.serialization. It allows to define serializers for custom types, delegating to Ktor and Kotlin serialization lib the dirty work.

commonMain {
  dependencies {
    ...
    implementation "io.ktor:ktor-client-core:$ktorVersion"
    implementation "io.ktor:ktor-client-json:$ktorVersion"
  }
}

androidMain {
  dependencies {
    ...
    implementation "io.ktor:ktor-client-android:$ktorVersion"
    implementation "io.ktor:ktor-client-json-jvm:$ktorVersion"
  }
}

iOSMain {
  dependencies {
    ...
    implementation "io.ktor:ktor-client-ios:$ktorVersion"
    implementation "io.ktor:ktor-client-json-native:$ktorVersion"
  }
}

Shared implementation

Once we finish the setup, we can implement the UserApi interface.

class SharedUsersApi : UsersApi {

    private val httpClient = HttpClient {
        install(JsonFeature) {
            serializer = KotlinxSerializer().apply {
                setMapper(
                    type = AllUsersResponseDto::class, 
                    serializer = AllUsersResponseDto.serializer()
                )
            }
        }
    }

    override suspend fun getUsers(): AllUsersResponseDto =
        httpClient.get("https://randomuser.me/api/?results=50")
}

In less than 20 lines of code we have a fully working implementation, usable on both the platforms.

We marked the getUsers method as suspend. It’s an interface method defined in a context where implementations could be long-running tasks. In our case, the Ktor Client uses Kotlin Coroutines to perform the HTTP call in background. Due to this, the HttpClient.get(String) method must be called in a suspend function or inside another coroutine. Knowing that, we chose to implement it as suspend, delegating the coroutine management to the caller. The class responsibility is only to fetch the users, not to explicitly manage background stuff.

Shrinking the model

All we have done is about the data-access layer of our application. We haven’t implemented any UI logic nor any UI widget.

By looking at the DTO, a question lights up immediately.
Do we really need all such fields?

Obviously, we don’t.

The domain of our application wants to know only some basic info about the user. Hence something like:

 data class User(
    val id: String,
    val name: String,
    val surname: String,
    val username: String,
    val email: String,
    val gender: Gender,
    val profilePictureUrl: String
) {
    enum class Gender {
        MALE, FEMALE
    }
}

Then we need to reduce the data obtained from the DTO to a simpler form. This mapping work will be implemented in a Repository class, in the common module. Such class allows to fetch all the users, hiding their origin. A basic repository pattern!

A pretty dummy implementation can be created as:

class UsersRepository(
    private val usersApi: UsersApi = SharedUsersApi()
) {
    suspend fun getAllUsers(): List<User> {
        val users = usersApi.getUsers()
        return users.results.map(::mapToUser)
    }
}

private fun mapToUser(result: AllUsersResponseDto.Result): User = User(
    id = result.login.uuid,
    name = result.name.first,
    surname = result.name.last,
    username = result.login.username,
    email = result.email,
    gender = if (result.gender == "female") User.Gender.FEMALE 
             else User.Gender.MALE,
    profilePictureUrl = result.picture.large
)

In the constructor we get an instance of UserApi, accessed by interface. For simplicity we set as default value a new SharedUserApi instance, that is the class we created before. In this way we can easily use it or replace it, as said at the beginning of the post.

Displaying the users in our Kotlin Native app

Well done guys! We have a fully working structure usable on both Android and iOS (…oh well, we can’t say it works until we write down some tests… but hey that’s the next post! ?).

Reached this point, all we have to do is to present that user list into the UI. At first, we can be tempted to start writing the code directly into an Android Activity or inside an iOS UIViewController. However, doing this is not exactly what we want. In fact, we want to maximize the code sharing between the platforms, mainly to avoid duplication of code and bugs.

In order to accomplish our purpose, we apply the Model View Presenter pattern to our UI code. Our Activity / UIViewController will implement a View interface. The Presenter will hold and instance of the View, removing the need to be coupled to the framework classes. In the Presenter then, we’ll write down the data manipulation code, for preparing the User models to be shown.

How to present users

First, let’s define how users should be presented in the UI. For the sake of example, our app will show a user in a simple row of a list. Each row will display the user name, the email, and the profile picture. Such minimal, much wow.

Having wrote down some “presentation ideas”, we create the model that will represent a displayed user:

data class UiUser(
    val id: String,
    val displayName: String,
    val email: String,
    val pictureUrl: String
)

We could have called it DisplayableUser, UserToShow… but UiUser was meaningful enough for the scope of this example.

The id in the model is used only for maintaining a simpler bidirectional flow. In fact, in such way we can reference the domain model starting from the displayable model.

Once defined how data will be presented, let’s define the View contract. This will explain how data are delivered to the UI. Also, it sums up the actions that the view will perform.

Since it will display a list of users, we’ll call it UsersListView:

interface UsersListView {
    fun showLoading()
    fun hideLoading()
    fun showUsers(displayableUsers: List<UiUser>)
    fun hideUsers()
}

Pretty immediate. Our Activity and UIViewController will respect this contract.

Present them!

Finally, we need to implement our Presenter class. We’ll call it UserListPresenter. Even this class will reside in the shared module, and thus will be written in pure Kotlin code. In fact, the UserListView is a key point to allow the Presenter to be framework-agnostic.

Our Presenter will expose two “lifecycle” methods:

  • attachView(v: UsersListView): the entry point. This will be called when the View is created. The Presenter will then store the reference of the given View as an instance property;
  • detachView(): the exit point. Will be called when the view is going to be destroyed. Here the Presenter will set to null the reference to the View. This helps us also to avoid retain cycles in Swift code.

Also, the Presenter will manage a CoroutineScope. In such way we’ll be able to launch Coroutines and perform all the repository work in the background.
We can take advantage of class delegation for this purpose. The Presenter will conform to the CoroutineScope interface, and we delegate the implementation to the MainScope() function. This usage is experimental, but we like to live in the edge.

Finally, in the detachView() method of the Presenter, we will call the cancel() method, made available by the CoroutineScope. This will cancel all the pending jobs.

At the end, our Presenter looks like this:

class UsersListPresenter(
    private val usersRepository: UsersRepository,
    private val backgroundDispatcher: BackgroundDispatcher
) : CoroutineScope by MainScope() {

    private var view: UsersListView? = null

    fun attachView(v: UsersListView) {
        view = v

        launch {
            view?.hideUsers()
            view?.showLoading()
            val users = withContext(backgroundDispatcher) {
                usersRepository.getAllUsers()
            }
            val displayableUsers = users.map(::mapToUiUser)
            view?.hideLoading()
            view?.showUsers(displayableUsers)
        }
    }

    fun detachView() {
        view = null
        cancel()
    }
}

How cool is this.

Once implemented the Activity and the UIViewController, the job is done.

But let me explain you a drawback.

Background dispatching

Notice that our Presenter takes as a constructor parameter also a BackgroundDispatcher instance. This is a class used to abstract the CoroutineDispatcher we are using. But why?

The Repository by definition is an object which works with data. Thus, is a good practice to perform its work in the background. Kotlin Coroutines allow background dispatching by using, for example, the Dispatchers.IOobject. While used on the Android platform, all goes well.

The problem resides in the Kotlin Native implementation used in the iOS target. Background dispatching is not yet supported, due to the complexity of managing object references between threads. The feature seems to be planned for a future release, but right now only the Main thread dispatcher is available. You can find the Github issue here.

That being said, then we cannot use the Dispatchers.IO object. For overcoming this issue, we created a BackgroundDispatcher which is an expect object. In the Android codebase is “actualized” using Dispatchers.IO, while in the iOS codebase is “actualized” using the Main dispatcher.

This doesn’t mean that the REST call will be made on the Main thread. Ktor Client sends computation in the background by itself. However, all the subsequent processing will take place on the UI thread.

In my opinion, this is and acceptable tradeoff for mobile applications that don’t require hard work in a background thread. In fact, threading might be safely handled by some other data-access library, as Ktor, so the application may not need to handle work deferral by itself.

Conclusions: our Kotlin Native every day app

We successfully build a Kotlin Native Multiplatform application. And look how cool it is:

The result of the Kotlin multi platform application.
The final application on both Android and iOS.

With a pretty architecture, we maximized the code sharing, starting from the presentation layer and even reaching the data layer.

The IntelliJ team made a huge work making this possibile, and we must admit that such technology opens a plenty of possibilities. More to say, I believe Kotlin Native / Multiplatform started walking the road to become a standard in multi platform development.

The multi platform projects are suitable also for other environments. You can build your backend using Ktor Server targeting JVM, and then share models with a frontend common module. Such module will contain all the logic we discussed about in this blog post. Further, it will be used by other platforms modules, like Android, iOS, JS and JVM desktop. And, obviously, it will contains tests!

The next blog post will talk about unit testing in Kotlin Native MPP! You can find all the sources of this post in the Github repository.

If you liked this post, feel free to comment it or tweet about it! Don’t forget to mention @damianogiusti and @MOLO17srl! ?

Have a nice Kotlin and thanks for reading!

Combined use of Firebase Authentication and Firebase Cloud Firestore in Android – Part 1

Nowadays, nearly all Android projects we work on use REST Service. Using methods like GET, POST or DELETE you can send, receive or delete data from a Backend. But what you think if i told you that there’s a solution if you cannot have your own Backend or if there are some path to the request that confuse you? Don’t get me wrong, REST is great, but Google comes to simplify our lives with the Firebase suite with few components like Firebase Authentication and Firebase Cloud Firestore!

Firebase works similar to hosting, you choose what services you need, connect them in your application and Whoa! You’re ready to see people who use your app all around the world! This is AWESOME! ?

Your goal for this tutorial is to build an app that handle users sign-in/login and their basic info (like employee’s role). In this first part you’ll focus on Firebase Authentication.

Getting Started

In order to start working, you need to Add Firebase dependencies to your Android project.

To be able to add them you need also a file called google-services.json, that contains all the configuration Firebase uses internally. Then, let’s start creating a new Firebase Projects!

First of all go to Firebase website and login using a Google account and when ready click the Go to console in the upper right corner of the page. You’ll now create a new Firebase Project clicking on Add project button like below:

Add a project in Firebase console

Choose your project name and select your current country.

Finally click on Create Project button. After the project creation confirm message click Continue. Now you should see the project dashboard! Next you have to add an Android application to the project, then click on the Android badge to add it:

Choose project target platform in Firebase console

Compile the package name field with your app package (in my case is: com.fm.federico.authfirestorepoc) and click on Register App. Finally follow the instructions on the Firebase page to add the google-services.json file to the project and click Next.

Now you can enable the Authentication service of Firebase. Click on Authentication in the left bar and select Access Method tab. You have multiple choice of authentication, we will use the simple e-mail and password method then click on E-Mail/Password, enable and save your choice. Under Users tab you will now be able to add new users with their e-mail and password, every time you will add a user firebase will assign an UID. The UID will be used in Firestore to identify which role the single user belongs to (you will use it in the second part of the tutorial).

It’s time to add Gradle Dependencies, let’s go! ?

First of all add the following dependency to the project-level build.gradle:

Dependency in build.gradle file

Finally add the library dependencies to the app module build.gradle:

Library dependency in build.gradle file

Hit Sync now and let Gradle do The Magic! ?

Now, Hands on code!

Here we go, the final step of this first part of the tutorial. In order to handle Register and Login you have to create the UI of the app that let the user insert e-mail and password for Login and, in case, the role for Register like:

Login page of the demo app

In this specific case we have three simple text field and two button, moreover in my example this activity implements theOnCompleteListener<AuthResult> from com.google.android.gms.tasks.OnCompleteListener to handle the completion for the login or sign-in task of our app.

For the Login button you will use the signInWithEmailAndPassword method of Firebase that start the authentication with the service. You can set the click listener for the button and call the method with:

login_button.setOnClickListener {
     auth.signInWithEmailAndPassword(
          email_edit_text.text.toString(),  
          password_edit_text.text.toString()
     ).addOnCompleteListener(this)
}

While, for the Register button, you will use the createUserWithEmailAndPassword method of Firebase that start the creation of a new account with the service. You can set the click listener for the button and call the method with:

register_button.setOnClickListener {
     auth.createUserWithEmailAndPassword(
          email_edit_text.text.toString(), 
          password_edit_text.text.toString()
     ).addOnCompleteListener(this)
}

In both case auth is an instance of class FirebaseAuth that you can retrieve with FirebaseAuth.getInstance()

Finally, in your onCompletion implementation you can start the flow you desire when the task of authentication or registration is successful or failed. In my example my implementation is like:

override fun onComplete(task: Task<AuthResult>) {
        if (task.isSuccessful) {
            MainActivity.newInstance(this).let(::startActivity)
            finish()
        } else {
            Toast.makeText(
                 baseContext, 
                 "Authentication failed.",      
                 Toast.LENGTH_SHORT
            ).show()
        }
 }

Finally… Firebase Authentication setted up

Firebase automatically login the user if choose to start the registration flow, then you don’t have to start the login flow after the registration. Just relax Firebase is here for you! ?

Here we go, the app for the first part of this tutorial is ready! You can run and enjoy it!

Thanks for reading and stay tuned for the second part where we see the integration with Cloud Firestore!

You can find all the code in this Github repository: https://github.com/MOLO17/AuthFirestorePOC

Kotlin inline classes, such magic

Starting with Kotlin 1.3, the standard library ships with a new cool feature: inline classes.

Inline classes in Kotlin

Kotlin inline classes are a nice and clean way to add strong typings to your code. They are meant to remove the heap overhead involved when creating wrapper types for simpler types or even for primitive ones.

You can declare a new inline class like you do with your data classes, but with the limitation that an inline class can hold just a single property.
While at compile-time they appear like normal classes or data classes, at runtime the type is represented using the type and the value of the property defined. That’s why only a single parameter is allowed.
The behavior is the same as the inline functions, where the body of the function is added instead of the function call.

Kotlin inline classes can also have methods, but cannot have stored properties different from the one defined into the constructor. At runtime, the method calls are represented as static method calls.

Let’s say that we have a StringWrapper inline class, which has the method greet().

inline class StringWrapper(val string: String) {
    fun greet() = "Hello, $string!"
}

StringWrapper("Damiano").greet()

The compiler will translate the invocation as a static method call, like

StringWrapperKt.greet("Damiano");

Inline classes can also implement interfaces. And this is the point of this blog post.

I want to tell you a little story, which will denote the magic behind inline classes. The story has Kotlin 1.3.21 as main character.

Once upon a time…

In a project for a customer of ours, we have a form which the user can fill that is completely driven by a customer’s backend service, that was already in place at the project’s start. By consuming it, the Android app receives a JSON descriptor and renders a list of UI controls based on it. When the user finished to fill them, he/she can perform a submit to a REST endpoint. If not treated carefully, the managing of the form items can be tricky. Specially when sending the data to the backend using a JSON DTO.

For a particular case, we needed to make an abstraction for a field of the DTO. Such field, in certain cases, could hold a plain string value and a three-properties object in others.
We defined a marker interface, ProductValue. Then we defined the two implementations, named respectively StringProductValue and PropertiesProductValue.

Magic happens

Since StringProductValue was meant to contain only a plain string, we decided to try out the new inline classes feature in Kotlin.

inline class StringProductValue(val value: String): ProductValue

How cool is this! We wrap our string value adding a stronger and meaningful type as StringProductValue. And we didn’t add any overhead, since at compile time the class will be directly unwrapped by the compiler to a plain String, and seen as a String at runtime.

Say that again.

At compile time the class will be directly unwrapped by the compiler to a plain String, and seen as a String at runtime.

In fact, the problem occurred when trying to pass an instance of our StringProductValue inline class to a method that accepted an instance of the abstract type ProductValue. At compile time we had no issues, but at runtime we received a ClassCastException.

java.lang.ClassCastException: java.lang.String cannot be cast to my.package.ProductValue

In a nutshell, the method which maps the value to the DTO accepts a ProductValue interface implementation, but at runtime our implementation class is seen as a java.lang.String, thus an exception is thrown just by calling such method with the “unwrapped” string.

For our use case, a data class suited better and obviously fixed the issue.

TL;DR – When to use Kotlin inline classes

Use Kotlin inline classes responsibly. You can let them implement interfaces and you can add methods to them. However, making abstractions using interface implementations made with inline classes isn’t fully supported right now. Moreover, it can lead to unexpected runtime errors.

In conclusion, I must say that inline classes are a very powerful feature. But they are still experimental, and there must be a reason for that.

Have a nice Kotlin and thanks for reading!

PS. don’t forget to follow my other articles about the Kotlin programming world: https://blog.molo17.com/tag/kotlin/

A trip into Kotlin Multiplatform Projects – Part 2: BLE

In the first part, we started discovering how powerful Kotlin Multiplatform is applied into the mobile app world. We explored the idea behind it, we discovered the concepts of expected and actual together with some problems that may occur, and we took as an example a basic Bluetooth Low Energy (BLE) devices discovery library.
But we want more.

After the implementation of the common discovery module and the two basic applications (Android, iOS), I decided to improve the Kotlin module, allowing the platform-specific implementations to perform simple operations according to the BLE protocol. I wanted the BluetoothAdapter class to be able to connect to a BLE device, discover its Services, and for each service its Characteristics. The goal was to implement an integration with the Xiaomi Mi Band 2, a well-known smart bracelet and fitness tracker, which has been largely hacked by some passionate users that developed third-party apps on it (you can find some interesting projects on Github). The Band has a single button on its hardware, which allows to display one by one the fitness data it acquired. My intention was just to listen to the button touch events, and deliver a message to the user in the app every time the band’s button gets tapped.

Pretty simple idea, but still challenging.

A bit of context about the BLE protocol

Before starting, you need to know a bit about the BLE protocol that we’re going to need for this Kotlin project. In a nutshell, most of the devices (commonly called peripherals) conform to the Generic Attribute profile (GATT), which is a generic specification for sending data between devices using Bluetooth. A peripheral can be a Client that sends GATT commands (i.e. smartphone), a Server which receives such commands and returns responses, or both, in particular cases. The communication between the two entities is made by operating on the server’s characteristics. On each of them, many of operations can be performed, like read, write and notify. In particular, the notify operation allows the client to receive server-initiated updates, ideally like push notifications. That was the case of my button press events.
Each peripheral exposes various services, which are scoped groups of characteristics. UUIDs are used for uniquely identifying the mentioned entities.
A cool reference can be found here, if you want to know more.

Let’s start with this Kotlin BLE project!

For communicating with a peripheral, at first you need to know what kind of services and characteristics it exposes. I used a well-known application called LightBlue for this. It’s pretty simple to use and you can examine all the peripheral info. By looking also on the Github projects I mentioned before (in particular here), I discovered the Mi Band’s service and characteristic which provides notifications when the button gets tapped.

// BLE devices share a common UUID for identifying services and characteristics. Only 4 digits in the first UUID segment are different.
private const val SERVICE_BUTTON_PRESSED = "FEE0"
private const val CHAR_BUTTON_PRESSED = "0010"

I started by defining a common interface for connecting to a peripheral and querying its services and characteristics. Using the expect/actual paradigm, the final definition looked like this:

expect class BluetoothAdapter {

    var listener: BluetoothAdapterListener?

    fun discoverDevices(callback: (BluetoothDevice) -> Unit)

    fun stopScan()

    fun findBondedDevices(callback: (List<BluetoothDevice>) -> Unit)

    fun connect(device: BluetoothDevice)

    fun disconnect()

    fun discoverServices()

    fun discoverCharacteristics(service: BleService)

    fun setNotificationEnabled(char: BleCharacteristic)

    fun setNotificationDisabled(char: BleCharacteristic)
}

As you can see in the methods signatures, I made some minimal abstractions on the platform-specific implementations of the peripherals, services and characteristics, to let the common codebase work independently on them.

expect class BluetoothDevice {
    val id: String
    val name: String
}

data class BleService(
    val id: String,
    val device: BluetoothDevice
)

data class Ble Characteristic(
    val id: String,
    val value: ByteArray?,
    val service: BleService
)

Notice that I marked BluetoothDevice as an expectation. This is due to the fact that I needed to keep together the Android BluetoothDevice and the iOS CBPeripheral with the actualization of the BluetoothDevice.

Kotlin BLE – Android module

actual data class BluetoothDevice(
    actual val id: String,
    actual val name: String,
    internal val androidDevice: BluetoothDevice
)

Kotlin BLE – iOS module

actual data class BluetoothDevice(
    actual val id: String,
    actual val name: String,
    internal val peripheral: CBPeripheral
)

For gaining access to services and characteristics, you need usually to follow some steps, which may vary between Android and iOS. First, you need to connect to the device (good point, man!). Once connected, start the services discovery and then discover the characteristics you need for each service.

For easily describing in which state the process was, I defined a sealed class in the shared module, which at the end looked like the below:

sealed class BleState {
    data class Connected(val device: BluetoothDevice): BleState()
    data class Disconnected(val device: BluetoothDevice): BleState()
    data class ServicesDiscovered(val device: BluetoothDevice, val services: List<BleService>): BleState()
    data class CharacteristicsDiscovered(val device: BluetoothDevice, val chars: List<BleCharacteristic>): BleState()
    data class CharacteristicChanged(val device: BluetoothDevice, val characteristic: BleCharacteristic): BleState()
}

The state instance is emitted by the BluetoothAdapter calling a BluetoothAdapterListener interface method. I choose this paradigm because all the steps were asynchronous (as you can imagine).

interface BluetoothAdapterListener {
    fun onStateChange(state: BleState)
}

Then, I implemented my BluetoothAdapter for the two platforms. The actual implementations were pretty straight-forward. Also, I added some shared UI logic applying MVP, but I’ll cover this topic in the next post, I promise you.

As I mentioned before, the steps of discovering services and characteristics are different between the two platforms. On iOS you need to manually start the discovery of characteristics for the service you are interested to, and for accomplishing this need, I exposed a method in my BluetoothAdapter class. On the contrary, on the Android platform, when you discover a service you can access to all his characteristics for free.

But why?

Probably, the Android engineers thought that once discovered a service, a user wants to play at once with its characteristics. And probably, the Apple engineers restricted the immediate access for security reasons. Perhaps for the same reasons why on Android you get the peripheral MAC address for free, and on iOS you need to explicitly request it instead. But this is another story.
Also, be aware of threading. On the Android platform, each callback method of the BluetoothGattCallback (called when a service is discovered, when a device is connected etc.) is called from a background thread. This can cause issues if you execute some UI related code in your listener implementations.

Well done! Your Kotlin BLE app is on the way

Cool, I implemented using Kotlin multiplatform class which allows BLE communication!
When I first run it on Android I was excited…

But!

But my enthusiasm was brought down early.

The characteristic discovery worked great, and so did the notification enabling. But guys, I was not able to receive the button taps notifications.

It was so ironic and so weird that I fully implemented a multiplatform application, and the only failure point was the platform related code! Luckily, was not my fault. At least, not at all.

For connecting to the Mi Band 2, your device needs to the be authorized by the Mi Fit application, and you need to perform the GATT connection by choosing the Band from the list of the already bonded peripherals. Probably, when connected to it, its app writes to a characteristic some info that let the Band to keep alive the connection. A fact I noticed is that after short time the Mi Band dropped the connection to a device without the Mi Fit app installed and configured.

Once I installed my multiplatform app on my personal phone where I have my Band’s data, all worked great.

After compiling against iOS, I found another problem with the iOS framework that was generated and embedded into Xcode. At first, the BleState.CharacteristicChanged class of my Kotlin codebase had the property characteristic named char, for simplicity.

I think you can figure out the issue ?

Solution of problem

When compiling for the iOS target, all your code is visible from your Swift project by using Objective-C header files. And we all know that char is the name of a type in Obj-C. The issue was that the generated header file contained a syntax error in the class declaration, as you can see in the below screenshot.

Once I refactored it, the error obviously disappeared.

So, the moral of the story is: always use meaningful names.

Ok sorry not really the case.

And so the moral of the story is: always use names which will not clash with reserved keywords of your target platform.

More multiplatform-ish.

End of the Klotin BLE project

I would like to take advantage of the problems I faced for underlining that Kotlin MPP did not give me any strange problem or unexpected error by itself, since all the multiplatform stuff worked as expected. The problems I found were due to a third-party limitation (in the case of the Mi Band) and to a misuse of the API (the iOS syntax error).

I’m very fascinated by this powerful technology, and I think I’ll start advocating for it’s adoption in some incoming projects, where it will be opportune.

Conclusion

But the trip didn’t reach the end! We explored a MPP using the Bluetooth, which is not a common use case for our beloved mobile applications. In the next part of this series, we will discover how to fetch some data from the network and deliver them to the user adopting a MVP pattern… all flavored with some hot Kotlin Coroutines spices.

Stay tuned, thanks for reading!

You can find all the code behind this project in this Github repository: https://github.com/MOLO17/kotlin-mpp-poc


A trip into Kotlin Multiplatform Projects – Part 1

We at MOLO17 are always looking for new technologies that can boost our productivity and allow us to deliver software at its best. Since 2017 we started adopting Kotlin with profit as the main language for developing Android applications. After a huge project is entirely written with JetBrains’ language, I personally started believing that this new technology is going to introduce a breeze of innovation in modern software development. Recently, I invested my time studying the Kotlin Multiplatform Feature.

Kotlin Multi Platform

Kotlin Multiplatform (or MPP, Multiplatform Project) is a powerful tool that combines Kotlin/JVM (which compiles into JVM bytecode), Kotlin/JS (which compiles into Javascript) and Kotlin/Native (which compiles into low-level binaries) together allowing a developer to write a common codebase entirely in Kotlin, specialize it with some platform-dependent implementations, and ship a software which runs on the JVM (or Android), on the web and, why not, in your iPhone. And when I say that runs, I mean that runs absolutely well.

Cool, isn’t it?

Some of you may argue that this is yet another way to write a cross-platform mobile app, like the Cordova or Ionic frameworks using JS, or Xamarin using C#.
But this is not what the people behind Kotlin Multiplatform MPP meant when designing this technology.
Just by looking on how the project will be structured by following the JetBrains’ guidelines, we can state that the principle behind this kind of multiplatform concept is code sharing. It’s made possible by defining in a common module the Kotlin pure definitions and implementations of entities and classes. In this module, all your business logic, presentation logic and – with the right libraries – data-access logic will take place. The rule of thumb is always to be framework-agnostic.
The Kotlin Academy Portal application developed by Marcin Moskala is just one of the proofs of the feasibility of these intentions (https://github.com/MarcinMoskala/KtAcademyPortal).

Completely amazed by these features, we at MOLO17 started a R&D department dedicated to the multiplatform development.
As a Software Engineer with a main focus on the Android platform, I started some projects for mastering the Kotlin Multiplatform.

The Kotlin Multiplatform project

The first project I developed was a simple Bluetooth mobile library, for the Android and iOS platforms: the goal was to write a common API for both the environments, for a simplified access to the Bluetooth framework.  
I started by creating the project following the documentation at Kotlin’s website. Pretty easy to setup and get running. The cool thing I really appreciated is that we can create a MPP directly from Android Studio! So no need to install IntelliJ (which I personally already have, but if you don’t, you don’t need it for this purpose).
The first-step expectation was an API that allowed the developer to start the discovery of BLE peripherals. So I started defining the common interface for this class, something like this:

expect class BluetoothAdapter {
    fun discoverDevices(callback: (BluetoothDevice) -> Unit)
    fun stopScan()
}

The expect keyword in Kotlin Multiplatform

Notice the expect keyword at the beginning of the class declaration. In the Kotlin Multiplatform context, the expect keyword defines an entity (a class, a method, a property, or even a constructor) that the developer is declaring in the common module and is expected to be present in the target platforms. By “expecting” such entity, the developer needs also to “actualize” it in the platform-dependent module, using the actual keyword. A sort of interface-implementation paradigm, but more dynamic. And here comes the sugar.

Kotlin Multiplatform – Android Target

When targeting in Kotlin Multiplatform the Android platform, nothing’s different with the implementation you’ll do with a standard project approach. You need our lovely god Context object, from which you get a BluetoothManager and then you can access to the system BluetoothAdapter instance.
A powerful feature on the expect/actual paradigm is that if you expect a class, you’re not required to expect also the constructor of that class. So in my case, I was able to create the actual definition that required a Context instance in the constructor, which allowed me to implement the definition as I wanted to.

actual class BluetoothAdapter(
    private val context: Context
) : ScanCallback() {

    // ...
    
    actual fun discoverDevices(callback: (BluetoothDevice) -> Unit) {
        this.callback = callback
        bluetoothAdapter.bluetoothLeScanner.startScan(this)
    }

    actual fun stopScan() {
        bluetoothAdapter.bluetoothLeScanner.stopScan(this)
        callback = null
    }
}

Kotlin Multiplatform – iOS Target

More sugar comes when targetting the iOS platform. Apart from the benefits you get by not using Xcode, you get other advantages by using Kotlin as iOS programming language. The Kotlin lib offers bridges classes which translates the Obj-C system APIs (like CoreBluetooth in our case) in Kotlin classes. That allowed me to implement the iOS “actualization” of my Bluetooth class using CB, writing in Kotlin. Awesome.

I instantiated the CBCentralManager as usual, I set a CBCentralManagerDelegate instance to it and started receiving the discovered peripherals. Notice also that when translating protocol to Kotlin, the compiler adds the Protocol suffix to the base name.

At first, I wanted to make my actual class named BluetoothAdapter implement the delegate protocol directly. Hence, I did it. But since the CBCentralManagerDelegate implements the NSObjectProtocol, I was required to let my actual class implement also the methods defined by this protocol. To avoid to implement them, I let the class extend from NSObject, for having the required methods already implemented. All went well until I tried to use my class definition into a Swift project. The compiler failed with the following error:

'BluetoothAdapter' is unavailable: Kotlin subclass of Objective-C class can’t be imported
Xcode compiler error due to unavailability of BluetoothAdapter
Xcode compiler error due to unavailability of BluetoothAdapter

Obj-C headers

By looking into the Obj-C generated headers, I saw that my BluetoothAdapter class was correctly compiled but marked as unavailable with the above message, and so I was not able to instantiate a new one or even define it as property type.
After some googling, I figured out that this behavior is a wanted limitation for avoiding potentially complex inheritance trees with the Foundation classes on the Kotlin side (according to the never-trust-anyone philosophy, I must say).
Obtaining an instance of my class then was not possible. I declared in Kotlin a function that returned and instance of my type, and when compiled the return type became NSObject. Hence I wrote down my two cents.

In a nutshell, we can use a class which inherits from Foundation objects only from the Kotlin side, and if we need to create an instance of it from Swift code, we need to create a builder function in Kotlin, because Kotlin knows how it’s defined and how to create it. Something like this:

fun makeBluetoothAdapter() = BluetoothAdapter()

actual class BluetoothAdapter: NSObject() { ... }

And then in the Swift implementation:

private let myClass = ConsumerClass(
    bluetoothAdapter: BluetoothAdapterKt.makeBluetoothAdapter()
)

Our Kotlin codebase of our Kotlin Multiplatform’s project will know the type of the instance we pass with the bluetoothAdapter label, and all will work correctly.

Now, let’s go back to my original purpose. I left my actual class without any extension, and I eventually created an object property subclassing NSObject and implementing the CBCentralManagerDelegate protocol.

actual class BluetoothAdapter {

    // ... 

    private val delegateImpl = object : NSObject(), CBCentralManagerDelegateProtocol {
        override fun centralManager(
            central: CBCentralManager,
            didDiscoverPeripheral: CBPeripheral,
            advertisementData: Map<Any?, *>,
            RSSI: NSNumber
        ) {
            // ... 
        }
    }


    private val manager = CBCentralManager().apply { delegate = delegateImpl }

    actual fun discoverDevices(callback: (BluetoothDevice) -> Unit) {
        // ...
        manager.scanForPeripheralsWithServices(null, null)
        onDeviceReceived = callback
    }

    actual fun stopScan() {
        manager.stopScan()
        onDeviceReceived = null
    }
}

Conclusion

And here we go! A common class and the platform-specific implementations.
Following the JetBrains’ guidelines, I was able to add as Build Phase a script that launches the Gradle task for producing the Cocoa framework file, embeddable into an Xcode project.

I developed two simple apps, Android with Kotlin and iOS with Swift, that show a list of the discovered devices using the common module. The result was great: the Bluetooth discovery worked flawlessy as if it was implemented in the standard way thanks to Kotlin Multiplatform.

The following step was the integration of a standard BLE protocol communication… Presented in the next part of this blog post! Thanks for reading!

Cover image credits: blog.jetbrains.com