Sitemap

Software Architecture Review: About Sport Fans

7 min readNov 30, 2023

I believe that documenting previous experiences in software design is crucial for clarifying ideas and keeping them in mind for the future. Here, I make an effort to share the challenges and solutions related to business requirements that arise, aiming to recognize the value delivered.

  1. Background and context
  2. Base Architecture
  3. Environments Challenge
  4. Development Desicions
  5. Implementation of Main Features & UX patterns

Background and context 🔎

The system is utilized by two main actors: a Sports Fan and a Journalist. The Sports Fan consumes news articles on an existing website (system), while the Journalist creates these news articles. The business model relies on Google advertisements.

The business aims to capture the mobile user market and facilitate growth. There are two brands under the same business — one specific to a particular country and the other catering to the rest of the world. The primary sports focus is on soccer, although users can also follow American football, baseball, and tennis.

To manage tasks such as updating team shields, specifying main team colors, prioritizing news articles, and implementing promotions, a CMS maintainer is essential for te new system.

Base Architecture 🏠

Environments Challenge

According to our brand strategy, we require two separate apps: one for Brand A and another for Brand B. Each app needs to be deployed on both the Google Play Store and the Apple App Store. While both apps share the same underlying logic, they differ primarily in terms of brand styling and data sources.

In the realm of mobile development, terms like release and debug modes are common. Additionally, distinctions are made between production and staging APIs. As a result, it becomes necessary to establish a clear separation in the development process, outlining procedures for creating an installable app versus debugging.

We required a mechanism to generate and deploy an app on the Android platform, such as Brand A in Release mode pointing to the production API. This is represented as android:brandB:production:release for deployment on the Play Store.

We need to create an artifact that spans across different environments, considering the following parameters:

  • Platform: Android or iOS
  • Brands: A or B
  • APIs: Production or Staging
  • Mode: Release or Debug

The strategy to address this involved using scripting to create and manipulate files. This included various resource files such as colors, assets, Firebase configurations, and other configurations, for both operating systems: Android and iOS.

  1. The script is invoked with an entry like: ‘set-environment.js <requestedApp>’ where an example of ‘<requestedApp>’ is ‘android:brandA:production:release’.
  2. The script then identifies and collects the required resources, including files and strings, based on the input provided in step 1.
  3. Subsequently, it generates the final files necessary to initialize the requested app
  4. The application initiates with the specified configuration.

For example, Firebase configurations necessitate resources such as GoogleService-Info.plist for iOS or google-services.json for Android. In order to cover all possible configurations, we need a total of eight files.

BrandA-Production-GoogleService-Info.plist
BrandA-Staging-GoogleService-Info.plist
BrandB-Production-GoogleService-Info.plist
BrandB-Staging-GoogleService-Info.plist
BranA-Production-google-services.json
BranA-Staging-google-services.json
BranB-Production-google-services.json
BranB-Staging-google-services.json

Then the flow is:

While solving this configuration, the ‘mode’ was ignored, but it remains relevant for other configurations and files.

Development Desicions

The final set of four apps — Brand A for Android, Brand A for iOS, Brand B for Android, and Brand B for iOS — share almost all their logic and utilize common features of smartphone devices. Therefore, the chosen framework for developing these apps was React Native. Given the team’s familiarity with React for web development, opting for React Native was a natural choice.

For testing purposes, we employ a continuous deployment strategy and integration tests using Detox.

We leverage Firebase for analytics, login and registration, funnel strategies, user data management, real-time databases, and push notifications…

For our continious deployment decision, we needed a way to deploy apps quickly. To do this we separated two types of deploy, a react native code deploy (without library update or new library in the code) and a release deploy (updating or introduce a new library). To make react native code deploys we use Codepush.

In the case of a release deploy, we take advantage of the opportunity to update existing libraries or introduce new ones.

User retention: Implementation of Main Features & UX patterns 🤖

I define ‘User retention’ as the factors that prevent a user from uninstalling the app.

Notify users about events of their favorite teams implementation

To enhance user retention, we required a system notification feature to inform users about their preferences events. For instance, users can receive notifications about events from a soccer match involving their favorite team. To make this feature feasible, we needed an API that allows us to request information about live games and a system notification mechanism. If a user selects multiple teams, they can customize the types of notifications to adjust their frequency.

Game result UX pattern

In the matches view, our requirement was to have a matches list always centered on today’s matches, yet with the option to explore the future calendar. This was achieved by implementing the following UX pattern.

The implementation detail relies on query parameters to retrieve matches of the day. Tabs are dynamically calculated based on the current date on the smartphone, enabling seamless navigation not only for today’s matches but also for subsequent days.

News articles UX pattern

The UX pattern for news articles is practically the same:

However, there’s a slight difference in the implementation. While the days remain static, featuring tabs like ‘Today,’ ‘Tomorrow,’ ‘Day after Tomorrow,’ and ‘DD/MM’, the news tabs exhibit dynamism. The only static tab is the ‘Related Favorite Teams News’ tab, while the others are configured by the App-Backend with the CMS maintainer. This flexibility is crucial, as it allows dynamic tabs to be provided based on specific events. For example, during the World Cup event, a dynamic tab is provided by the App-Backend with a custom URL for news related to this specific event..

Match info UX pattern

Information about a match can vary based on factors such as its importance or relevance. For matches in significant leagues or those deemed highly relevant, the granularity and amount of information provided are more extensive. To design this, we can separate components like

If a match cannot provide information for Component B, for example, this component will not render. Therefore, components are rendered dynamically based on the available information.

As evident in these three types of information, we applied the same pattern, developing a custom component that supports this UX pattern for information presentation, and we successfully reused it three times. Utilizing a consistent pattern for different kinds of information allows users to explore the entire app quickly and easily. Additionally, we strategically place ads between some items.

Live match chat implementation

We implemented another important feature: the live match chat. Users can engage in a chat during any live match. Within the match item, users can view current results, access the match streaming if available, and participate in a chat to share their reactions with other fans watching the match.

Anonymous User implementation

While it can be inconvenient to require users to sign in with social media accounts like Google, Facebook, Apple ID, etc., as many users prefer not to sign in to apps, there is a specific type of user who distinguishes themselves from others by saving anonymous preferences. Fortunately, Firebase offers a solution for this issue through the ‘Anonymous user’ feature.

App Backend

There are two modules in the backend. One serves as a bridge between private APIs and custom links, providing data to the mobile app. The second module is the CMS, where a maintainer manages assets for teams, including colors and custom links for match results, live match links, and notification settings, among other tasks. External systems provide APIs for news and game results.

Final Architecture 🚀

Conclusion

This serves as a concise overview of the architecture and patterns employed, with certain details omitted for enhanced clarity. Any suggestions you may have are welcome.

If you want to learn more about the business and product vision, I invite you to review this brief, which includes screenshots of the apps.

Main Tools 🦾

  • Firebase: Utilized for push notifications, analytics wrapper, anonymous user support, and real-time database, among other functionalities.
  • Codepush: Enables the deployment of updates without requiring app updates on stores.
  • Detox: Employed for React Native integration testing on both Android and iOS platforms.
  • Strapi: Used as a CMS for managing content.
  • Excalidraw: Utilized for creating drawings in this article.

--

--

Jon Colque
Jon Colque

Written by Jon Colque

I focus in language-agnostic solutions, share programming tips, and advocate for clean code and clean architecture in development

No responses yet