Server Driven Compose

May 13, 2024 | Programming

License API Build Status Profile

Server Driven Compose showcases server-driven UI approaches in Jetpack Compose with Firebase.

The purpose of this repository is to demonstrate the following:

  • Implementing server-driven UI using Jetpack Compose and Firebase Realtime Database.
  • Defining rendering protocols (such as layout nodes, action handlers, and versioning) and consuming them as composable functions in Jetpack Compose.
  • Establishing component design systems for consuming rendering protocols on the client side, along with versioning systems for these design components.
  • Gaining a deeper understanding of the Firebase Realtime Database system.
## Technical Content If you’re interested in the overall design systems and implementation details of this project, check out the blog post below: – [Design Server-Driven UI with Jetpack Compose and Firebase](https://getstream.io/blog/server-driven-compose-firebase) ## Tech Stack – Open-source libraries – Minimum SDK level 21. – [Kotlin](https://kotlinlang.org) based, utilizing [Coroutines](https://github.com/Kotlin/kotlinx.coroutines) + [Flow](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx/coroutines/flow/package-summary.html) for asynchronous operations. – Jetpack Libraries: – Jetpack Compose: Android’s modern toolkit for declarative UI development. – Lifecycle: Observes Android lifecycles and manages UI states upon lifecycle changes. – ViewModel: Manages UI-related data and is lifecycle-aware, ensuring data survival through configuration changes. – Navigation: Facilitates screen navigation, complemented by [Hilt Navigation Compose](https://developer.android.com/jetpack/compose/libraries#hilt) for dependency injection. – [Hilt](https://dagger.dev/hilt): Facilitates dependency injection. – Architecture: – MVVM Architecture (View – ViewModel – Model): Facilitates separation of concerns and promotes maintainability. – Repository Pattern: Acts as a mediator between different data sources and the application’s business logic. – [Firebase Android KTX](https://github.com/skydoves/firebase-android-ktx): Kotlin Compose-friendly Firebase extensions designed to help you focus on your business logic. – [Retrofit2 & OkHttp3](https://github.com/square/retrofit): Constructs REST APIs and facilitates paging network data retrieval. – [KSP](https://github.com/google/ksp): Kotlin Symbol Processing API for code generation and analysis. – [Landscapist Glide](https://github.com/skydoves/landscapist#glide), [animation](https://github.com/skydoves/landscapist#animation), [placeholder](https://github.com/skydoves/landscapist#placeholder): A pluggable, highly optimized Jetpack Compose and Kotlin Multiplatform image loading library that fetches and displays network images with Glide, Coil, and Fresco. ## Running This Project on Your Side You can run this project on your side following the guidelines below:
  1. First things first, download the following JSON file on your local PC: Gist: JSON demo for Timeline UI.
  2. Following the Firebase setup guidelines, download the google-services.json and place it into the app directory on this project.
  3. Next, set up the Firebase Realtime Database in your Firebase dashboard. Once that’s done, you can import the JSON file.
  4. Next, create a file named secrets.properties in the root directory of this project, and copy-paste your Realtime Database URL into it, as shown in the example below:
    REALTIME_DATABASE_URL=https://server-driven-compose-default-rtdb.asia-southeast1.firebasedatabase.app
  5. Build the project.
## Architecture **Server Driven Compose** fetches data from Firebase Realtime Database and makes it an observable flow in the data layer. The presentation layer then takes this data and assembles it into components, which are formatted to be consumed by UIs as composable functions. ![architecture](figurearch.png) ### Component Design System **Server Driven Compose** retrieves all rendering information from the backend (Firebase Realtime Database), allowing the client to focus solely on consuming the layout details. This approach lets you concentrate on how to do (rendering) rather than what to do, a decision typically made by the product manager. The code below, which demonstrates the simplicity of the main (timeline) screen implementation in Jetpack Compose, captures this idea:
kotlin
Column(
    modifier = Modifier
        .background(ServerDrivenTheme.colors.background)
        .fillMaxSize()
        .padding(12.dp)
        .verticalScroll(state = rememberScrollState()),
    verticalArrangement = Arrangement.spacedBy(12.dp)
) {
    timelineUi.components.forEach { uiComponent ->
        uiComponent.Consume(
            version = timelineUi.version,
            navigator = { clickedComponent ->
                navigateToDetails.invoke(clickedComponent, timelineUi.version)
            }
        )
    }
}
### Component Versioning **Server Driven Compose** demonstrates a versioning system for each component and how to synchronize them with the application in real-time. ![import](figureimport-json.png) ### Design Patterns **Server Driven Compose** adheres to the MVVM architecture and implements the Repository pattern, aligning with Google’s official architecture guidance. The architecture of **Server Driven Compose** is structured into two distinct layers: the UI layer and the data layer, each fulfilling specific roles and responsibilities. ### Architecture Overview ![architecture](figurefigure1.png) – Each layer adheres to the principles of unidirectional event-data flow: the UI layer sends user events to the data layer, and the data layer provides data streams to other layers. – The data layer operates autonomously from other layers, maintaining purity without dependencies on external layers. This loosely coupled architecture enhances component reusability and app scalability, facilitating seamless development and maintenance. ### UI Layer The UI layer encompasses UI elements responsible for configuring screens for user interaction, alongside the ViewModel, which manages app states and restores data during configuration changes. ## Modularization **Server Driven Compose** adopted modularization strategies below: – **Reusability**: Modularizing reusable code properly enables opportunities for code sharing and limits code accessibility in other modules at the same time. – **Parallel Building**: Each module can be run in parallel and reduces build time. – **Strict Visibility Control**: Modules restrict exposure to dedicated components, preventing them from being used outside the module. – **Decentralized Focusing**: Each developer team can assign their dedicated module and focus on their own modules. For more information, check out the Guide to Android app modularization. ## Troubleshooting If you run into issues while setting up or running the **Server Driven Compose** project, try the following steps: – Double-check your JSON file and ensure it’s correctly downloaded. – Make sure the path for the **google-services.json** file is accurate. – Verify that your Firebase Realtime Database is set up correctly and that you have the necessary permissions enabled. – Ensure that your app has access to the internet. – If data isn’t showing as expected, check your connections and responses from the Firebase database. For more insights, updates, or to collaborate on AI development projects, stay connected with **[fxis.ai](https://fxis.ai)**. At **[fxis.ai](https://fxis.ai)**, we believe that such advancements are crucial for the future of AI, as they enable more comprehensive and effective solutions. Our team is continually exploring new methodologies to push the envelope in artificial intelligence, ensuring that our clients benefit from the latest technological innovations.

Stay Informed with the Newest F(x) Insights and Blogs

Tech News and Blog Highlights, Straight to Your Inbox