Building Freetrade

Building Reactive Applications at Freetrade

October 29, 2020

Senior Software Engineer Jimmy Thompson takes you through the three layers of the Freetrade app

Today I want to talk about a key element of our stack: our mobile apps. Of all the technical components that make up Freetrade, the app is entirely unique. It’s the primary way our customers manage their money and their investments.


If you build mobile applications, something you'll implement often is a way to fetch data, usually from some kind of API, and display it on the screen. You'll also likely need to implement a way to keep the content on that screen up-to-date while the screen is open.


The most basic way to do this is a refresh button, found in most web browsers. Other apps can let you pull-to-refresh, or secretly poll for updates in the background. Whichever you choose has a drastic effect on how the app feels.


While we don't really want to perpetuate the stereotype of flashing red and green tickers, and the kind of investing that's associated with that, it's important that customers feel connected to the stock market when making their investments.


To do this, our apps largely rely on Firebase and reactive programming.

Anatomy of a reactive mobile app

There are already great introductions to reactive programming, but to summarise, it's all about having the mobile app update the UI based on a stream of changes from the backend. We use a framework called ReactiveX, which has equivalent implementations in Swift and Java/Kotlin.


Our apps are structured in three layers:



  • Services, which subscribe to streams of data, as well as calling out to our backend;
  • View Models, which take the data from the services and transform it into something more useful for the screen where it will be displayed; and
  • View Controllers/Activities, which control the individual components on each screen.

Services

Services at Freetrade are where most of the data-fetching magic happens. They're generally separated by domain, like the InstrumentPricingService, which is responsible for fetching the latest prices for a given stock.


Thankfully, maintaining the current price of a stock is pretty simple. We rely heavily on Firebase, which plugs into our reactive codebase without much effort. When we call the currentPrice method on the InstrumentPricingService, it subscribes to the prices collection on Firebase, and gives us an Observable stream. When we save a new set of prices in Firebase, it notifies the InstrumentPricingService within the app. This effectively allows us to push the new price to all the screens which are currently viewing it.

View Models

View Models at Freetrade exist behind every screen in the app, as well as several individual components. They're responsible for deciding what data needs to be fetched, and what format it should be in, to make that view render properly.


At their simplest, they often just take data from the Services and push it to the View. However, they can also handle things like user input, pagination, sorting and navigating between screens.

The role of this particular View Model is to present a small summary of a stock. You might recognise it from several locations throughout the app. In order to display properly it needs several pieces of data, including the name of the stock and the logo. All we care about right now, however, is the current price.



View Models are where the bulk of the logic sits within the app. This is something we actively try to promote, as it sits between fetching data from Firebase, like the Services, and controlling UI elements, like the View Controllers and the Activities. Both of these are hard to test. By pushing logic into the View Models, and constraining all the inputs and outputs to be Observable streams, we’re able to keep the bulk of our mobile app code under unit tests. 

View Controllers/Activities

The final part of this puzzle, known as a View Controller on iOS and an Activity on Android, is all about managing the user interface. Now the Service has fetched the data, and the View Model has converted it into something useful, we can display our summary to the user.

We declare our price label, which sits on the right of the summary view. We then subscribe to every update to the View Model’s currentPrice field. Whenever the price changes, the View Controller is notified and adjusts the label to reflect the new price.


The last piece of this puzzle is house-keeping: how we’re disposing of subscriptions we no longer need. We only want to keep the numbers fresh on the screen that the user is currently viewing, anything more wastes the battery and mobile data. To prevent this, we tie our subscriptions to the lifecycle of the screen (or component) that requires them. When those screens are gone, the subscriptions are all cleaned up.


In ReactiveX, you clean up used subscriptions by disposing of them. In the example above, we throw all of our subscriptions into a Dispose Bag. When the view is closed, the View Controller is destroyed, and the Dispose Bag with it. When the Dispose Bag is destroyed, it cleans up all the subscriptions that were placed within it, closing the socket and preventing any further updates.

Bringing it all together

By having our interface react to changes happening further down our mobile stack, and by relying on Firebase to notify apps when things change, we've achieved a truly reactive mobile app with little effort.


This allows us to build UI components which are reusable, specifying their own data requirements, while ensuring values like the price of a stock are consistent everywhere they are shown. Other approaches usually require you to manually notify other views that the data has refreshed.

Building reactively at scale

So far, we’ve used Firebase for all of our data storage and data requirements within the app. As we've grown, we've made great use of it, but have also brushed against its limitations. Running an entirely reactive setup is a great time saver, but does require maintenance. Tools like Firebase can also cost a lot of money as your user base grows.


Having our mobile apps reading directly from Firebase has meant our database effectively doubles as a public API. This hasn’t really been an issue, but when we have to make breaking changes to a data structure in Firebase, we’re limited by an app release. This means reviews from Apple and Google, and a complete roll out of both of them.


We’ve been making good progress decoupling our apps from our backend schema. Our favourite involves using public and private collections. This means our backend interacts with a private collection, which is then used to regenerate a public collection read by the mobile apps.


For content that changes rarely, such as the user's name and address, we’ve realised we didn't really need to have the mobile app subscribe for updates to this data in real-time. For information like this, we’ve begun fetching it from a HTTP API. Thankfully our network libraries, Alamofire (iOS) and Retrofit (Android), also play very nicely with ReactiveX. Our layered architecture has meant we can swap how we fetch this data from within the Instrument Pricing Service without really changing any other part of the app. We’ll go through more on this in a future post.

We're always on the lookout for engineers to help build our mobile apps. If the above sounds fun, check out our careers page to find out more.

Building Freetrade

Earn 3% interest on cash in Freetrade Plus

Brand new for Plus members

1/12/2020

|

Sam Poullain

Building Freetrade

Lessons learnt with Cloud Firestore

Freetrade Head of Engineering, Invest, Tim Drew, shares how we scale our platform using Cloud Firestore

20/11/2020

|

Sam Poullain

Building Freetrade

Remote onboarding to a new job

Freetrade Software Engineering Manager Rokey Ge shares his virtual onboarding experience.

10/11/2020

|

Sam Poullain

Building Freetrade

Referring friends and earning free shares just got even easier

A big improvement to Free Share is here.

6/11/2020

|

Sam Poullain

Building Freetrade

Investment fees calculator

See how Freetrade compares to other brokers.

4/11/2020

|

Sam Poullain

Building Freetrade

600 brand new stocks, including David Beckham's Esports team

Gold miners, Twinkies, McDonald's and more.

2/11/2020

|

David Kimberley

Building Freetrade

Increasing the US order value limit

A new limit of £25,000 for US stocks.

2/11/2020

|

Sam Poullain

Building Freetrade

Brand new ETFs on Plus

Including fixed income, investment-grade and government bonds.

2/11/2020

|

Sam Poullain

Building Freetrade

How your product vision could put a human on Mars

Freetrade VP Product Duncan Leslie on vision, strategy and measuring success.

2/11/2020

|

Duncan Leslie

Building Freetrade

Stock fundamentals are now on your app

Market cap, dividend yield, and P/E ratio are here.

2/11/2020

|

David Kimberley

Building Freetrade

Introducing the time-weighted rate of return

Compare your performance against a global benchmark

2/11/2020

|

David Kimberley

Building Freetrade

It’s raining stocks: 500 new investment opportunities on your app now

2/11/2020

|

Viktor Nebehaj

Building Freetrade

The Freetrade Christmas List 2020

Everything we plan to add to your app before the holidays.

1/12/2020

|

Sam Poullain

Building Freetrade

Optimising cold-starts with Google Cloud Functions

Freetrade engineer Simon Poole talks about overcoming some serverless infrastructure challenges.

2/11/2020

|

David Kimberley

Building Freetrade

Over 450 brand new stocks

From Papa John's to Zambian cattle farmers, we've added a wide array of new stocks to the Freetrade universe

2/11/2020

|

David Kimberley

Building Freetrade

Celebrating Black History Month at Freetrade

Freetrade Talent Sourcer, Isabelle Atunrase, shares why we should all celebrate Black History Month, and some of the ways we’re getting involved here at Freetrade.

2/11/2020

|

Sam Poullain

Building Freetrade

100 new ETFs from iShares, Vanguard, VanEck, and more!

Our biggest addition of ETFs yet.

2/11/2020

|

Alex Campbell

Building Freetrade

User Story Mapping - How we keep a focus on value

Freetrade Senior Product Managers Anant Sangar and Glenn Drawbridge have been busy working on limit orders and SIPPs. Here, they chat through how use User Story Mapping.

2/11/2020

|

David Kimberley

Building Freetrade

400 brand new stocks, including 200 exclusively for Plus

More of what you want.

2/11/2020

|

Alex Campbell

Building Freetrade

Event sourcing on Freetrade

Freetrade Senior Software Engineer Luke Smith talks about the nuts and bolts of our brokerage platform

13/11/2020

|

David Kimberley

Building Freetrade

New stocks coming to your free plan and Plus subscription

Introducing your expanded stock universe.

11/11/2020

|

Alex Campbell

Building Freetrade

Money-weighted rate of return

More ways to measure your portfolio performance

2/11/2020

|

Sam Poullain

Building Freetrade

Our first Open Banking integration is rolling out

It’s now even easier to add money to your Freetrade account

2/11/2020

|

Sam Poullain

Building Freetrade

How to land a role in Product Management

Freetrade Senior Product Manager Glenn Drawbridge shares his story.

2/11/2020

|

Sam Poullain

Building Freetrade

Announcing the Tesla free share winner

2/11/2020

|

Sam Poullain

Building Freetrade

Introducing Freetrade Plus

Find out what's inside, and request your invite.

11/11/2020

|

Duncan Leslie

Building Freetrade

Brand new stocks: fashion brands, fast food, biotech innovators, and another SPAC

Over 100 new stocks, including Kodak, La-Z-Boy, Tiffany & Co, and Crocs.

2/11/2020

|

David Kimberley

Building Freetrade

Meet our new Head of People, Amy Gilman

Amy joins Freetrade as our first Head of People.

2/11/2020

|

Sam Poullain

Building Freetrade

Brand new stocks: fashion brands, gold miners, and SPACs

100 stocks inc. Avis, Tripadvisor, Goodyear, AMC Entertainment, Denny’s

2/11/2020

|

David Kimberley

Building Freetrade

Your new order experience is here

The first of many additions to order types.

2/11/2020

|

Sam Poullain

Building Freetrade

Brand new stocks: fresh IPOs, Latin American stocks, and investment trusts

75 new stocks including Ericsson, Yelp, Gfinity, Youdao

2/11/2020

|

Sam Poullain

Building Freetrade

28 brand new ETFs and 70 new stocks

Country-specific ETFs, and stocks from Wendy’s to Columbia

2/11/2020

|

Sam Poullain

Building Freetrade

Brand new: ETFs, Korean telcos, Japanese app and Chinese airlines

100 brand new stocks and ETFs are here

2/11/2020

|

Sam Poullain

Building Freetrade

Cloud computing, ETFs, UK stocks and brands from AB Inbev to Dominos

This week's 100 new stocks and ETFs might be the best batch yet.

2/11/2020

|

Sam Poullain

Building Freetrade

Brand new stocks: Banks, planes, trains and automobiles

Ferrari, Honda, Canadian Railway, United Airlines, Canadian banks, ETFs, and more

2/11/2020

|

Sam Poullain

Building Freetrade

90 brand new stocks have landed

You can now own a piece of Ed Sheeran

2/11/2020

|

Sam Poullain

Building Freetrade

Buy weed (stocks) on Freetrade

Cannabis companies have arrived

2/11/2020

|

Sam Poullain

Building Freetrade

Perry Blacher, serial entrepreneur turned VC, is joining Freetrade’s board

The former entrepreneur will be Freetrade’s non-executive director

2/11/2020

|

David Kimberley

Building Freetrade

Meet the team: Renata Labude, Senior Growth Manager

Find out more about how Free Share works

2/11/2020

|

David Kimberley

Building Freetrade

Introducing more stocks on Freetrade

250 new US stocks have landed

2/11/2020

|

Viktor Nebehaj

Building Freetrade

Fractional shares: the rollout has started

You can now invest in a slice of US companies

2/11/2020

|

Viktor Nebehaj

Building Freetrade

Meet the team: Caitlin Rich, Principal Product Designer

Meet the person responsible for making Freetrade look cool

2/11/2020

|

David Kimberley

Sign up for our newsletter

Download the app and start
investing now.