Featured Video


Project Description:

0. Structure


1. Concept

1.1. The Problem

1.2. The Solution

2. Apps

2.1. Introduction

2.2. Passenger App

2.3. Inspector App

3. Technologies and Validation Methods

3.1. Digital Tickets

3.2. Physical Tickets

4. Backend

4.1. Firebase Auth Service

4.2. Firebase Cloud Functions Service

4.3. Firebase Firestore Service

5. Analytics

6. Conclusion


1. Concept


1.1. The Problem

After diving deep into the problem, I would like to analyze the two different use cases (on board inspections and station exit inspections) in a separate way, since they have unique particularities. Let's start with the station exit inspections use case and let's get some answers to the following questions:

  • Station Exit Inspections:

“A second method is when multiple inspectors stand at station exits, inspecting all passengers leaving a station. In this case speed is required to prevent long waiting times and overcrowding.”

  • How many passengers will be inspected?
    • All passengers!
  • Is this a problem for the inspector?
    • I don't think so, they are doing their job, they will do it if they have 10 or 300 passengers and if it takes 5 minutes or 60 minutes to inspect all passengers.
  • Is this a problem for the passenger?
    • This is definitely a problem for the passenger! If for some reason there are too many passengers to be inspected or not sufficient inspectors to validate all the tickets this will result in long waiting times and no one likes that! 
  • If currently only 10% of the passengers use digital tickets (provided data), why should the passenger use an app widget or an app feature that allows to access their ticket extremely fast if in the end of the day they still have to wait in line like everyone else?
    • No answer needed for this one :)

On Board Inspections:

“Tickets are checked by personnel in stations and vehicles. The time it takes to check a ticket is essential, as ticket inspectors try to check as many tickets on board as possible between two stops.”

  • How many passengers will be inspected?
    • Some of them! (As many as possible, but not all of them!)
  • Is this a problem for the inspector?
    • I don't think so, they are doing their job, they will do it if they have 10 or 300 passengers and they will try to inspect as many passengers as possible.
  • As inspectors inspect on average 12 passengers between 2 stations (provided data), do they care if they only scan on average 10 passengers, do they have any motivation to increase this value?
    • As much as they want to do a good job, I don't believe that they care because they earn the same salary every month and they don't have any motivation to do more.
  • Is this a problem for the passenger?
    • As much as the passengers might respect the inspectors, I don't think they will miss their exit in order to be inspected.
  • So, if this is not a passenger problem neither an inspector problem, how do you solve a problem that is nobody's problem?  
    • You can't!
  • What technology, app widget or app feature can solely solve this problem?
    • None!
  • Since this is not a passenger problem neither an inspector problem, who has this problem?
    • This is a business problem!

1.2. The Solution

Before I explain my idea I will divide passengers into 3 different categories:

  • V0 Passengers - Passengers that use physical tickets;
  • V1 Passengers - Passengers that use digital tickets and don't like to share their data;
  • V2 Passengers - The next generation of passengers, passengers that don't mind giving some data for a better quality service.

My solution consists in simplifying the validation process and creating a gamification system that compensates the V2 Passengers for the data that they are willing to exchange. How can this work?

  • The Inspector Role:
    • How can we simplify the current validation system?
      • Since we have a new player in town, the backend server, that is able to validate a lot more things with more precision, has an uniform behavior and is able to do all those things faster, let it handle that task!
    • So what is the "new" role of the inspector?
      • The inspector has a major role in the validation process but they no longer need to identify the problem, so their task is easier. The server will identify the possible problem or validation check that must be performed by the inspector (e.g., validate a student card, validate an extra passenger identity) and the inspector executes the required validation and informs the server about the required validation result with a simple "Confirm" or "Reject". If the server doesn't find any problem, the passenger will be on its way a few milliseconds after the QR Code scan.

  • The Wallet QR Code:
    • Currently each ticket has an unique QR Code to validate its authenticity, but since the server performs the core validation now, is that really needed?
      • No, for digital ticket users, the use of a QR Code per ticket no longer makes sense as the server has all the ticket information stored in a database, meaning that a single QR Code is able to identify the passenger account is enough. This way, no time will be wasted on finding the valid ticket or some specific information in one of the tickets.

  • The Gamification System:
    • A few years ago everyone was crazy with a game called Pokemon Go, the game required users to share there GPS location and the game would place pokemons for a period of time in different geo locations that could be caught if the user was nearby? This sounds crazy, right? 
      • Yes, but it was a success!
    • So, what does this game for kids has to do with our problem?
      • Well in Pokemon Go, there was a trade of data (GPS location) for the possibility to catch pokemons. Why don't we do the same? Why don't we trade data (App open and Bluetooth enable) for a better quality service where these new generation of passengers (V2 passengers), the players, could save money and time?
    • How would they save time? 
      • A new type of lane will be created in station exit inspections, the "Fast Lanes", where only V2 passengers with authorization from the backend server can access (an algorithm will be used to label a passenger as a trusted / not trusted and as having a valid ticket). By only allowing V2 passengers with valid digital tickets to the these lanes will result in lower waiting times. 
    • How would they save money?
      • By creating daily, weekly, monthly or even yearly prize draws where giveaways, promotion discounts in next purchases, partner services, local businesses, museums and points of interest for tourists (we can label tourists as new users with foreign phone numbers, this would require the phone number to be a mandatory field in the registration process).
    • Why do we need passengers to have the app open and the bluetooth enable when they are using the public transports?
      • By having the app open and the bluetooth enable is the only way to associate a passenger to an inspector location, in other words, the passenger device could detect a signal that is being constantly transmitted by the inspector device (bluetooth advertising) and perform 2 different actions:
        • Display a local notification "Inspection Time" informing the passenger that an inspector is close;
        • Send a message (bluetooth advertising) to the inspector device with passenger unique identifier.
    • What is the inspector role in this process?
      • The inspectors will be the pokemons in the analogy, they are placed in different locations (inspections) for different periods of time. This way, every time a passenger device gets in the range of the inspector device bluetooth signal, the passenger will be automatically identified and if a valid  ticket is associated to that account at that time, the passenger will be added to the daily prize draw eligibility list.
    • How does this help us in the validation process if we can only identify passengers with valid tickets instead of passengers with invalid tickets which was what we were looking for?
      • In on board inspections some passengers will be constantly feeding the system with their identifiers, while others rarely or never turn their bluetooth on, so when a station exit inspection comes, the server will be able to know exactly who can access the fast lanes and who can't, based on each passenger feeding ratio.

In the medium term it will create a snow ball effect and most passengers will become V2 passengers, which is exactly what we are looking for!

2. Apps


2.1. Introduction

Two different apps were developed using Google's UI toolkit Flutter, as it allows to build Android and iOS apps in a single codebase. As described in the pre-selection phase the idea for the passenger app was to replicate some screens of Wien Mobil App and build new features on top of that. Being versatile and having a simple user interface to interact with were the main priorities for the inspector app, as this is a working tool to validate tickets, all the small detailed features that can save some time are a must have. Both apps use open source plugins and all the selected plugins work on Android and iOS but might have some different behaviors in specific use cases due to some operating system restrictions. QR Code, Bluetooth Low Energy (BLE) and Near Field Communications (NFC) were the technologies used to transfer data between the two apps, while http over the internet was used to communicate with the backend server.

2.2. Passenger App

Main Screen 
Wallet QR Code 
Buy Ticket 
Lines / Stations 
Map Screen 

2.2.1. Screens and Features

  • Main Screen - After reading a lot of reviews from the Google Play Store and Apple App Store most of users reference a simpler UI from an older interface, I wasn't able to find any screenshots from this older app but since user might use the app for different purposes, I would go for the menu version since I'm one click away from all the functionalities (I'm not an UI/UX expert so this is my humble opinion as a simple user);
  • Wallet Screen - The wallet concept can be seen as a folder where tickets can be stored and there is one wallet per device, this way if the user sign in in multiple devices, multiple wallets will be created. This decision will make sure multiple devices can't use the same ticket in inspections. Of course user will want to transfer their tickets/passes to a different device, my suggestion is to allow these ticket transfers between devices from the same account but with a delay, e.g., annual passes can be transferred but the pass will only be available in the new device after 48h, different times could be applied for the different types of ticket. Since all the QR Codes will have to be scanned and there is a new player in town, the backend server, I believe that a single Wallet QR code is more practical than a QR Code per ticket, this way users don't even have to access their tickets tab, providing their ticket faster. Most common QR Codes have static data, this one has dynamic data (all the details are in the technology Digital Ticket QR Code section);
  • Buy Ticket Screen - Just like in your current app, multiple categories with multiple products can be found. Some products will require different fields to be filled. Multiple screens to select the starting point station, the direction, the university and the type of airport transfer were implemented. The main feature here is the notifications screen in the end of the purchase process where the user will be able to select when he would like to be notified, this notification will be a quick access to the wallet QR Code. All the notifications are local and will be scheduled for the desired time;
  • Lines/Stations Screen - Since I needed this data for the inspector app, I've decided to implement the 2 screens where we can find all the existing lines and stations (For demo purposes, only the underground stations were implemented);
  • Map Screen - The Map Screen was entitled as "Explore" should be used only for users that really need the map view to see the station location (this could be an offline feature) and to calculate their route to their desired destination. Maybe the drawer menu no longer makes sense for this screen since there is the bottom navigation bar now.

2.2.2. How to access the QR Code Screen 

  • Pre-Scheduled Local Notification (On ticket purchase) - As displayed in the "Buy Ticket" .gif in the previous section, after a passenger buys new tickets, a new screen was added to the process where it is possible to configure when he would like to be notified. The idea of this notification is receive it while the passenger is using the transports and if he finds an inspection he opens and accesses the wallet QR Code in a click. Since the notification times are setup and confirmed by the passenger there is a bigger probability that the notification can work as expected;
  • Instant Local Notification (Nearby Inspection, Bluetooth required) - This notification will only work for devices that have the app open (in foreground or in background) and bluetooth must be enabled (ideal solution to interact with V2 passenger's devices). Once an inspector is closed the passenger device will be able to detect the inspector bluetooth signal and automatically launches the local notification;
  • App Shortcut - This solution is valid for all passengers that actually know what an app shortcut is;
  • App Widget - Users will use app widgets if they add some kind of value to their life. The current WienMobil provides that, a widget that can be completely customizable by the user and the 50% usability by the digital users proves that. A simple widget with the QR Code on it would be one of the fastest ways to access their wallet QR Code, but would the users actually use it? What kind of value is added to their lives? Do they care that much about transport ticket inspections or validation times? I don't think so, for that reason I gave up on this solution. Adding a button to the current Wien Mobil App Widget would be a preferable option in my opinion since it would automatically be installed in 50% of the current digital users;
  • Digital Wallets - Digital wallets are here to stay, I believe this would be a nice to have but I wouldn't considered this as the core of my solution, specially when the solution must work offline;
  • Samsung Bixby Button Shortcut - Some Samsung devices (e.g., Samsung S8+) has a special button to start Bixby, Samsung's Voice Assistant, and a predefined app can be open if there is a double click on that button. This should be by far one of the fastest solutions to access the wallet QR Code but that are the chances of the user to configure WienMobil app instead of other apps?





2.3. Inspector App



Create New Inspection 
Rejoin and Leave Inspection 

2.3.1. Screens and Features

  • Main Screen - Each inspector can have zero or one active inspection, these active inspections should be created on a daily basis or more than one per inspector in order to keep the data well segmented. One of the inspectors is responsible for creating the inspection (the inspection owner), display the inspection QR Code so other inspectors can join the same inspection and to keep the settings updated;
  • Settings Screen - The inspection owner is the only one who can change the inspection settings, all the other inspectors will only be able to view the settings. All the inspectors will be listening for changes in the inspection settings stored on the backend server database, this way, every time the inspection owner changes something, the new settings will be automatically update on all the inspector devices. This is ideal for on board inspections where stations are always changing, the inspection settings must be setup before starting the inspection and during the inspection two top screen arrow buttons will allow the owner to change the current station in a super simple way. By keeping the settings updated means that all the scans from that inspection will be associated to the exactly time and place;
  • Inspection QR Code Screen - The inspection QR Code can only be accessed by the inspection owner since he will be the responsible for adding other inspectors to the same inspection.
  • Inspection Join Inspection Screen - The non inspection owners will access this screen to scan the inspection QR Code displayed by the inspection owner. Once they scan the QR Code they are automatically added to the inspection, a log will be stored in the database and they are forwarded to the settings screen where they will be able to see the inspection settings;
  • Inspection Screen- The inspection screen is where inspectors will spend most of their time since this is the screen that can scan QR Codes, read NFC tags, advertise (broadcasting data over BLE) and scan data from other advertisers (passengers broadcasting data over BLE). All the described functionalities can be easily enabled or disabled using the rounded buttons in the sliding up panel. A few other option are available:
    • Inspection QR Code - Displays the inspection QR Code screen, this button is only available for the inspection owner;
    • Update Settings - Displays the inspection settings screen and allows the owner to change the inspection settings;
    • View Settings - Displays the inspection settings screen and allows all the non inspection owners to view the settings;
    • Search by Phone Number - This option should only be used in extreme cases and in conjunction with other identification card.
  • Inspection By Phone Number Screen - The passenger app should require to associate passenger's phone number when they register and the idea for this validation method is to be able to reach the passenger's ticket if they run out of battery, forget their phone somewhere, lose their phone or get their phone stolen. The text field where the phone number should not display the phone digits that are being introduced, this way, unless the inspector memorizes it, he won't be able to record or take a print screen of the passenger phone number;
  • Inspection Result Screen- When the camera scans a passenger wallet QR Code, the NFC reader detects a smart card or a emulated NFC device (smartphone) or the phone number search is triggered, this screen will display the validation result. The backend validation process results in a binary "succeeded" or "failed" result. 
    • If the backend validation process succeeds and no extra validation is required by the inspector (e.g., show student card or confirm extra passenger identity), a green background screen will be displayed and no passenger information will be displayed.
    • If the backend validation process succeeds and extra validation is required by the inspector (e.g., show student card or confirm extra passenger identity), an orange background screen will be displayed the device owner photo, name, date of birth and all the active tickets (tickets that expired on that day, valid tickets and future tickets) from that account device wallet will be displayed. To easily identify what is being requested by the backend server a clear message of what is being required will be displayed and the ticket(s) that are requiring that validation will be marked so the inspector can easily identify the problem and validate what is being requested .
    • If the backend validation process fails, extra validation will be required by the inspector (e.g., identify if the passenger identity matches the owner of the scanned passenger account), a red background screen will be displayed the device owner photo, name, date of birth and all the active tickets (tickets that expired on that day, valid tickets and future tickets) from that account device wallet will be displayed. To easily identify what is being requested by the backend server a clear message of what is being required will be displayed and the ticket(s) that are requiring that validation will be marked so the inspector can easily identify the problem and validate what is being requested. 

3. Technologies and Validation Methods


// Category Ticket Table (1 bit)
// 0 - physical
// 1 - digital
export const CATEGORY_DIGITAL_TICKET: number = 0x0;
export const CATEGORY_PHYSICAL_TICKET: number = 0x1;

// (Passenger Used) Technology Table (3 bits)
// 000 - qrc (QR Code)
// 001 - ble (Bluetooth Low Energy)
// 010 - nfc (Near Field Communications)
// 011 - phn (Phone Number)
// 1** - Reserved for other technologies
export const TECHNOLOGY_QRC: number = 0x0;
export const TECHNOLOGY_NFC: number = 0x1;
export const TECHNOLOGY_BLE: number = 0x2;
export const TECHNOLOGY_PHN: number = 0x3;

// (Passenger Used) Digital Ticket Access Tracking (Feature/Widget Used) (4 bits)
// 0000 - Local notification configured when the ticket was purchased
// 0001 - Local notification triggered by the inspector inspection BLE signal
// 0010 - App Widget
// 0011 - App Shortcut
// 0100 - Main Screen
// 0101 - Main Screen -> Wallet 
// 0110 - Drawer -> Wallet
// 0111 - FloatingActionButton (App in Foreground)
// 1*** - Reserved for other features
export const DIGITAL_TICKET_TRACK_APP_WIDGET: number = 0x2;
export const DIGITAL_TICKET_TRACK_APP_SHORTCUT: number = 0x3;
export const DIGITAL_TICKET_TRACK_DRAWER_TO_WALLET: number = 0x5;
export const DIGITAL_TICKET_TRACK_ACTION_BUTTON: number = 0x6;
export const DIGITAL_TICKET_TRACK_MAP_TO_WALLET: number = 0x7;

// (Passenger Used) Physical Ticket Access Tracking (Feature/Widget Used) (4 bits)
// 0000 - Online store
// 0001 - Station machine
// 0010 - On board
// 1*** - Reserved for other features
export const PHYSICAL_TICKET_TRACK_ONLINE_STORE: number = 0x0;
export const PHYSICAL_TICKET_TRACK_ON_BOARD: number = 0x2;

3.1. Digital Tickets

3.1.1. QR Code (QRC) - Currently Working 

  • The passenger QR Code can have 2 different formats:
    • 00ZxXEQ2Dni5bWBBpVwGqczyJL6vc2.61e7b5809d68f9b5.270221.220005.
    • 00ZxXEQ2Dni5bWBBpVwGqczyJL6vc2.61e7b5809d68f9b5.270221.220005.789acb
  • The first byte '0' indicates that is a digital ticket and corresponds to qrcode technology;
  • The second byte '0' indicates that the tracking app feature method used to access the wallet qrcode was a purchased local notification (check previous code to understand the values);
  • The 'ZxXEQ2Dni5bWBBpVwGqczyJL6vc2' is the passenger unique identifier;
  • The '61e7b5809d68f9b5' is the passenger device identifier;
  • The '270221' is the UTC date in 'ddMMyy' format (27.02.2021);
  • The '220005' is the UTC time in 'HHmmss' format (22:00:05);

The '789acb' is the inspection code (hexadecimal characters only), this code will only be added to que QR Code if the user has the bluetooth on and is detecting an inspector BLE Signal.

The inspector QR Code scanner is extremely fast and the error correction capabilities make it an extremely powerful tool for the inspector job.

Normally QR Codes are static or dynamic (normally matching an URL), here I wanted to have a dynamic capabilities and the introduction of the date and time, allow to have an extra check and dynamic characteristics. 

3.1.3. Bluetooth Low Energy (BLE) - Currently Working

The BLE plugin need bluetooth on and gps on, this is a plugin limitation. In android docs there if we use some service provided by them, the gps option won't be required.

  • I didn't want devices to connect over BLE so I'm just using the advertising capabilities (Broadcasting);
  • The advertising data follow the iBeacon protocol in order to work with Android and iOS devices;
  • The inspector device is always advertising an UUID, for example: "39ED98FF-2900-441A-802F-9C3980C199D2"
  • Most of the uuid character can be used to identify the business and have some changing values like date and time like I did with the QR Code data. Here I've used the last 6 values 'C199D2' as the inspection id.
  • The last 7th value, the '0' indicates the inspection id (0 - station exit inspection, 1 - on board inspection) since different behaviors could be triggered depending on the inspection type;
  • When the uuid matches the expected patter (using a regex);
  • The passenger saves the inspection identifier;
  • Replaces the last 12 values for its unique ble identifier 'BBBBBBBBBBBB';
  • Places the inspection id in the first 6 values of the uuid and the 7th and 8th values will be used for the header codes, already explained in the QR Code module;
  • The passenger will transmit the uuid "C199D22F-2900-441A-802F-BBBBBBBBBBBB"
  • Where the 2 indicates (digital ticket, using ble technology) and the F is not being used since the user doesn't need to interact with the app to transmit this ble signal, it is automatically triggered when an inspection ble code is detected;
  • The inspector is scanning for uuids starting with their inspection id and when detected, extracts the first 8 values and stores in a set that acts like. Since the inspector can get many uuids, the ble scanner saves the detected uuids in a set and from time to time send an http request to the backend server with all the scanned ble ids;
  • The passenger ble broadcaster stops after a few seconds (configurable).

3.1.2. Near Field Communication (NFC)

Not implemented yet

3.1.4. Phone Number (PhN)

Not implemented yet

3.2. Physical Tickets

3.2.1. QR Code (QRC)

Not implemented yet

3.2.2. Near Field Communication (NFC) - Currently Working 

  • The NFC must be on before opening the app (BUG);
  • Only working for 4 byte UUIDs and 7 byte UUID, the uuids must be hardcoded in the firebase;
  • Reads the card serial number, converts to hexadecimal value and see if matches any entry from the database.

4. Backend


Backend Server - Google's Firebase

4.1. Firebase Auth Service 

Takes care of all the authentication process, currently the Email/Password Sign-in method is the only option enable, to recreate as much as possible your current app (WienMobil), where the phone number and photo are as optional fields. With my solution I would change it to a Phone Sign-in method to create a more personal connection with the users and a more secured solution, which will make sure users don't create multiple accounts as much as they can do with email based solutions. Every time a user logins a Json Web Token (JWT) access token is issued from the server, after some time this token expires and a new token is requested by using a refresh token (something with a bigger expiration data) this is all done behind the scenes by the auth service.

4.2. Firebase Cloud Functions

Runs on Node.JS with the web application framework Express. Two different routers, one that handles server side logic for the passenger app (Ex: Buy a new ticket) and one that handles server side logic for the inspector app (Ex: Validate some passenger wallet QR Code). This is executed from a server located in Belgium (eur3 (europe-west) zone). In this project all the cloud function calls are done over http, where non authenticated http requests will be ignored. This way all the http requests must have an Authorization header with a value "Bearer " followed by the current JWT access token obtained by the auth service. Since this is a serverless solution, the first http call will always take some time to get the function up and running taking between 1 to 2 seconds when called from Portugal, following http calls, including validation checks are taking from 200 to 350 milliseconds when called from Portugal. These times should be even faster in Vienna since Vienna-Belgium is approximately 1100 km while Lisbon-Belgium is approximately 2000 km.

  • (cloud function http base url)/api/v1/inspector
    • Endpoint: /inspect - Validates if a physical or digital source is associated to a valid ticket.
    • Endpoint: /reject - If the inspector is requested to identify the passenger, this call rejects the validation result provided by the server validation process (previously invoked in the /inspect endpoint).
    • Endpoint: /confirm - If the inspector is requested to identify the passenger, this call confirms the validation result provided by the server validation process (previously invoked in the /inspect endpoint).

  • (cloud function http base url)/api/v1/passenger
    • Endpoint: /buy - Ticket purchase process, the payment process part is not implemented in the MVP.
    • Endpoint: /access - Requests access to go over a station inspection fast lane.

4.3. Firebase Filestore Service

Is a NoSQL database that stores all the data needed for both applications to work properly, they work with the concept of a document (which is basically a Json Object) and a collection (that can store multiple documents). This is executed from a server located in Belgium (eur3 (europe-west) zone). The passenger and inspector accounts should follow the least privilege principle (principle of least privilege is the idea that at any user should have only the bare minimum privileges necessary to perform its functions) and these authorization rules can be defined in the Firestore Access Rules. For this MVP I've created the following collections:

  • passenger_accounts collection stores:
    • Passenger individual account information can be accessed by an unique user identifier (uid);

Path: /passenger_accounts/${uid}

  • Each account can be associated to multiple devices, to access each one, a device identifier must be provided (did);

Path: /passenger_accounts/${uid}/devices/${did}


  • Each device has its own wallet where multiple tickets can be stored (each ticket in inside a wallet that is associated to an account device, this way if I want to have access to a certain ticket it doesn't matter if I'm logged in on multiple devices with the same account, I need to have a specific device);


Path: /passenger_accounts/${uid}/wallets/${did}

  • Each ticket is associated to a single account device wallet and has an unique ticket id (tid) for that wallet (All the digital tickets follow this json pattern, some tickets might have some particular fields that will be stored in the metadata map. Physical Tickets follow the same pattern but don't have the device_id, device_name, user_id and display_name fields).

Path: /passenger_accounts/${uid}/wallets/${did}/active_tickets/${tid}

  • inspector_accounts collection stores:
    • Inspector individual account information can be accessed by an unique user identifier (uid);

Path: /inspector_accounts/${uid}/

  • Each account can be associated to multiple devices, to access each one, a device identifier must be provided (did);

Path: /inspector_accounts/${uid}/devices/${did}

  • Each account device can be associated to an inspection document and inspection history collection per device identifier (did). Each inspector can only be associated to one or zero inspections at a time, the document contains the details of the last inspection that the inspector joined, while the history collection has all the details of inspector's previous inspections). 

Path: /inspector_accounts/${uid}/inspections/${did}

  • challenge_accounts collection stores:
    • Passenger bluetooth low energy (BLE) unique identifier (bleid). Each passenger device wallet with a non expired ticket should be associated to one of these unique identifiers, when that passenger device wallet has no valid tickets, the bluetooth low energy (BLE) unique identifier should be detached from passenger device wallet path. Each bleid if formed by 12 hexadecimal values = 48 bits = 281474976710655 possible values. This bleid will be part of an unique identifier (UUID) that will be sent over bluetooth low energy network communications between passenger and inspector devices.

Path: /challenge_accounts/${bleid}/

  • inspections collection stores:
    • The inspection collection is segmented by date following the yyyy-mm-dd format (yyyy - 4 digits to represent the year, mm - 2 digits to represent the month, dd - 2 digits to represent the day). for each date there is a daily-inspection collection with multiple inspections created on that day. Each inspection has a unique identifier (inspectionId). Each inspection document has details about who created that inspection (owner), when was created, the inspectors list is a log list that will add a new event when an inspector creates, joins or leaves an inspection, the settings map has the current settings of that inspection. The type can be "on_board" or "station_exit", we can also find the transport category, line, direction, station and if it was a station exit inspection there should be an extra "exit" field. The idea is that a team of inspector join the same inspection and only the owner has permissions to change the settings. 

Path: /inspections/${yyyy-mm-dd}/daily-inspection/${inspectionId}

  • The multiple validations from different inspectors will be once again segmented by input method (qrc - QR Code, nfc - Near Field Communications, ble - Bluetooth Low Energy and phn - Phone Number). Every time one of the inspectors validates a ticket, all the current inspection settings will be associated to that validation. The power of the data in these documents is immense! Details about where, when, which inspector, which passenger, ticket category, technology used, input method and even passenger behavior on how did the customers accessed their,

Path: /inspections/${yyyy-mm-dd}/daily-inspection/${inspectionId} 

  • physical_tickets_nfc collection stores:
    • Smart cards have nfc tags which have unique serial numbers and can store data. These unique identifiers (nfc_hex_id) can have different lengths depending on the protocols used. For this implementation only two of the existing formats were used, one follows the ISO 14443-4 specification, is from type NfcB and has a 4 byte unique identifier (Ex: AA:BB:77:DD in Hexadecimal), while the other follows the ISO 14443-3A specification is from type NfcA and has a 7 byte unique identifier (Ex: AA:BB:77:99:CC:44:22 in Hexadecimal). 

Path: /physical_tickets_nfc/${nfc_hex_id}/

  • Just like wallets, introduced in the passenger_accounts collection, smart cards can be associated to multiple tickets. Each ticket has an unique identifier (ticketid) unique for that collection. Physical tickets are similar to digital tickets except the user details and device details.

Path: /physical_tickets_nfc/${nfc_hex_id}/active_tickets/${ticketid}

  • physical_tickets_qrc collection stores:
    • Passenger bluetooth low energy (BLE) unique identifier (bleid). Each passenger device wallet with a non expired ticket should be associated to one of these unique identifiers, when that passenger device wallet has no valid tickets, the bluetooth low energy (BLE) unique identifier should be detached from passenger device wallet path. Each bleid if formed by 12 hexadecimal values = 48 bits = 281474976710655 possible values. This bleid will be part of an unique identifier (UUID) that will be sent over bluetooth low energy network communications between passenger and inspector devices.

Path: /physical_ticket_qrc_collection/${bleid}/

  • line_catalogue collection stores:
    • The line catalogue collection has all the details about the transport system in Vienna, transport categories (Ex: underground), lines (Ex: u1), stations (Ex: Oberlaa) and station exists (Ex: Exit A). Since I wanted to use this information in my apps, I've collected all the data about the Underground lines and stations, for demo purposes there are 3 station exits for each station (Exit A, Exit B and Exit C). Colors were extracted from print screens of your current app.

Path: /line_catalogue/${categoryId}/

  • For each transport category line there is a json document that contains the names of all the stations that form that specific line in an ordered way by their index. Only the Underground stations were implemented. Station names were extracted from Wikipedia.

Path: /line_catalogue/${categoryId}/lines/${lineId}

  • For each station there is a json document with the names of the exits, for demo purposes there are 3 station exits for each station (Exit A, Exit B and Exit C).

Path: /line_catalogue/${categoryId}/lines/${lineId}/stations/${stationId}

  • station_catalogue collection stores:
    • This collection has all the station names indexed by their first 2 characters, this was created to be used in station name search that is required when a user buys a Single Card ticket. Once again, only the underground stations were implemented.

Path: /station_catalogue/${first_two_station_name_characters_in_lowercase}/

  • university_catalogue collection stores:
    • This collection has all the university names, this was created to be used when a user buys a ticket from the Tickets for Students category. This collection has a single json document with the name, latitude and longitude from the 21 universities from Vienna (Latitude and Longitude might not be 100% right since I did some fast google maps searches, some universities have departments in multiple locations and I simply selected one of them). The idea was to display the stations and universities in the map screen, but this task will have to be rescheduled for the next hackathon :)

Path: /university_catalogue/

  • ticket_catalogue collection stores
    • The ticket catalogue is segmented in different ticket categories, by selecting a category a json document with all the products of that category is returned.

Path: /ticket_catalogues/${categoryId}/

  • By selecting a product another json document containing all the details and required fields to be filled is returned.

Path: /ticket_catalogues/${categoryId}/prod_details/${productId}

PS: I wasn't able to upload the images of the last 2 json documents since the Taikai platform gives an error message every time I try to upload an image. All the data about this collection can be found in Firebase.

5. Analytics


5.1. Possibilities

Collected data with a simple scan:

  • Date
  • Time
  • Location
    • On board / Station exit
    • Transport Category;
    • Line;
    • Direction;
    • Station;
    • Station Exit;
  • Inspection
  • Inspector
  • Passenger
  • Scanned Method: QR Code (qrc), Near Field Communication (nfc), Bluetooth Low Energy (ble) and Phone Number (phn)
  • What feature/widget are passengers using the most to access their wallet QR Code (Offline analytics)
  • Identify and access data from data tempering tries

If so many details about a single scan can be collected imagine the power of a daily, weekly, monthly or yearly automatic generated report. In a decade where information is knowledge, this solution allows to understand the system in an easier and better  way allowing a step ahead in every business decision.

Ideas of how this data could be used to benefit all parties:

  • Better estimates of how many passengers use the public transports in a specific station at a specific time;
  • Better estimates of how many inspectors should be required for an inspection in a specific location and time run smoothly;
  • Place more inspectors in the lines/stations that have more validation failures;
  • Extra compensations for the better inspectors / inspector teams;
  • Label passengers based on how frequently they share data over Bluetooth;
    • Passengers that frequently share data will be labeled as V2;
    • Passengers that rarely share data will be labeled as V1.
  • Compensate V2 passengers by their data sharing in on board inspections by creating daily / weekly / monthly / yearly giveaways;
    • Discounts for the next purchased ticket;
    • Discounts in some partner products;
    • Discounts in museums for tourists;
    • etc.
  • Compensate V2 passengers in station inspections by giving them access to the fast lanes (See presentation to understand the fast lane concept);
  • Understand what technology is being used the most for ticket validation and understand why;
  • Understand customer behavior, what are the features / widgets that the users are using the most, this will help you understand what features are working as expected and which one should be improved or removed;
  • With digital solutions come new digital risks, someone, somewhere will try to hack the system. By having access to the reasons of why validations are failing patterns can be found to better understand what hackers are trying to break the system. 

6. Conclusion


Nowadays everyone is trying to save money and/or time in a way or another. By offering those two things for V2 passengers, V1 passengers will follow along after watching the benefits. Inspectors no longer have to decide things or suspect of someone, the backend server does that for them and they have a versatile app where they can scan digital or physical tickets (if they use QR Codes or NFC tags). 

The business gets:

  • Constant validation times;
  • No human error in the validation process;
  • More rigorous validation checks (Multiple checks to return a succeeded response);
  • Faster validation times;
  • Impartial and uniform judgement;
  • Satisfied V2 passengers, while nothing changes for V0 and V1 passengers will be tempted to try V2 technology for the associated benefits;
  • Passenger satisfaction increased;
  • Inspector satisfaction increased;
  • Adoption of digital tickets increased;
  • Costs of ticket production decreased;
  • Easier to create partnerships (e.g., small local businesses that are having a bad time in the COVID) that could provide discounts for their own businesses in the giveaways;
  • Big amounts of data that can help to understand the current state of the business and to help calculating in which direction the business should go.


Idea Description


Project Quick Check will be developed using two Google tools: Flutter (to build Android and IOS apps using the same code base) and Firebase (serverless cloud solution to handle the backend logic) to build two different apps (the User's App and the Inspector's App) that will use the best of different  technologies such as QR Code (Quick Response Code)NFC (Near Field Communications) and BLE (Bluetooth Low Energy) to accelerate and revolutionize the validation process of digital and physical tickets.

The user app will be inspired in the current Wien Mobil App, the features will be developed on top of that to have an instant perception of how the developed features could work in production, while the inspector's app will have a dark theme to preserve the device's battery life and an extremely simple user interface to facilitate the inspector's job.

There isn't a perfect way to accelerate the validation process but there are faster solutions when compared with the current one, where features like: App widgets, App shortcuts, Pre-scheduled Local Notifications, Digital Wallet Integrations* (Apple Pay and Google Pay) will be developed to handle the desires of different types of users and decrease the time it takes for the users to reach their tickets.

I'll introduce a brand new validation flow, designed by myself, that will decentralize the validation process where users will be able to validate their own digital tickets/passes directly with the server, this way they can skip the normal validation lanes and go to a special "fast lane", where a simple visual confirmation by the inspector will be required, creating such a better experience in the validation process for the end users.

The final solution will be able to handle different use cases, where the user and inspector experiences, fast validation time and accuracy will be the main priorities.

* This might not be possible to implement since Google Pay is not available in Portugal, only for payments and Apple Pay requires a developer account to be able to perform the integration, which costs 100€, but I'll see what I can do.

Team Presentation:



My name is Lourenço Correia da Silva, I'm 30 years old and I'm from Lisbon, Portugal.

I have a Master of Science (MSc) in Telecommunications and Computer Engineering from ISCTE-IUL with a score of 17/20.

I'm currently an invited teaching assistant at ISCTE-IUL (Portuguese Public University) with almost 5 years of teaching experience, where I was able to lecture the following Java courses:
- Introduction to Programming;

- Object Oriented Programming;
- Concurrent and Distributed Programming.

For 3 years I worked for different companies building web solutions in sectors like Image Processing, Banking, Energy and Music. I was able to work with technologies like Nativescript, Ionic, Angular, HTML, CSS, JS, Java, C++, C#, VB, Oracle, MySql, SQL Server, PostgreSQL.

2 years ago I've decided to join the startup world, I've been building some project with small teams and by myself in order to acquire all the skills that I need to build my own startup and execute my ideas. For the past 6 months I've been learning Mobile Development in Flutter and Cloud Computing with Firebase and AWS.

Photography and Videography are two of my hobbies, I've learn how to work with a camera, camera equipment, Adobe Lightroom and Adobe Premiere Pro to edit photos and videos respectively. I've been doing some photoshoots, wedding videos and some promotional videos for small brands.

I love a good challenge, I've been practicing this "one man army" thing for a while and I'm extremely confident in my skills and resilience.

I like to associate my name to the word "Quality" and I'll be able to build and deliver a quality solution for this problem.

My LinkedIn

Thank you,