feat: refine push notification handling and lifecycle support#14
feat: refine push notification handling and lifecycle support#14pitzcarraldo merged 4 commits intomainfrom
Conversation
- Ensure `onMessage` is called only in the foreground and introduce `onBackgroundMessage` for background scenarios. - Standardize internal variable naming and storage keys for clarity. - Update dependencies and add lifecycle support for foreground detection.
WalkthroughIntroduces release 1.3.2: updates changelog and README, adds androidx.lifecycle.process dependency, changes push notification routing so foreground uses onMessage and background/terminated uses onBackgroundMessage, renames several internal variables and storage keys, and adds sample app configuration loading; no public API signature removals detected. Changes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
clix/src/test/kotlin/so/clix/services/TokenServiceTest.kt (1)
53-53: Tests correctly updated to use new storage keys.The test updates align with the renamed storage keys in
TokenService.kt. However, these tests directly reference internal storage key strings, creating tight coupling to implementation details. Consider extracting the key constants or testing through theTokenServicepublic API where possible to reduce maintenance burden.gradle/libs.versions.toml (1)
22-23: Consider using Firebase BOM for version management.Per coding guidelines, Firebase should be managed via BOM and version catalog. Currently
firebase-messaginguses a direct version reference. Consider using the Firebase BOM for consistent Firebase dependency management across the project.+firebase-bom = "33.7.0" firebase-messaging = "24.0.0"And update the library entry to use BOM:
-firebase-messaging-ktx = { group = "com.google.firebase", name = "firebase-messaging-ktx", version.ref = "firebase-messaging" } +firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" } +firebase-messaging-ktx = { group = "com.google.firebase", name = "firebase-messaging-ktx" }Based on coding guidelines: "Use Firebase via BOM and version catalog".
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
CHANGELOG.md(1 hunks)README.md(1 hunks)clix/build.gradle.kts(1 hunks)clix/src/main/kotlin/so/clix/core/Clix.kt(5 hunks)clix/src/main/kotlin/so/clix/core/ClixNotification.kt(3 hunks)clix/src/main/kotlin/so/clix/services/TokenService.kt(1 hunks)clix/src/test/kotlin/so/clix/services/TokenServiceTest.kt(7 hunks)gradle/libs.versions.toml(3 hunks)
🧰 Additional context used
📓 Path-based instructions (14)
clix/src/test/kotlin/so/clix/**
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Mirror main source structure for unit tests under clix/src/test/kotlin/so/clix
Files:
clix/src/test/kotlin/so/clix/services/TokenServiceTest.kt
clix/src/{test,androidTest}/kotlin/**/*.kt
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
clix/src/{test,androidTest}/kotlin/**/*.kt: Use JUnit4/Kotest for unit tests and AndroidX Test/Robolectric for instrumentation
Name tests using Given-When-Then or 'it(target) should ...' style
Use property-based tests for pure functions where applicable
Use Stub and Spy patterns via MockK for doubles
Prefer Stub/MockK doubles for tests
Files:
clix/src/test/kotlin/so/clix/services/TokenServiceTest.kt
clix/src/main/kotlin/so/clix/**
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Follow the specified library source structure under clix/src/main/kotlin/so/clix/(core|models|notification|services|utils)
Files:
clix/src/main/kotlin/so/clix/services/TokenService.ktclix/src/main/kotlin/so/clix/core/Clix.ktclix/src/main/kotlin/so/clix/core/ClixNotification.kt
clix/src/main/kotlin/so/clix/services/**/*.kt
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
clix/src/main/kotlin/so/clix/services/**/*.kt: Classes interacting with external services must use Service or Repository suffix
Handle side effects explicitly within repository/service classes
Files:
clix/src/main/kotlin/so/clix/services/TokenService.kt
clix/src/main/kotlin/so/clix/{core,services}/**/*.kt
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Throw exceptions only for unrecoverable errors
Files:
clix/src/main/kotlin/so/clix/services/TokenService.ktclix/src/main/kotlin/so/clix/core/Clix.ktclix/src/main/kotlin/so/clix/core/ClixNotification.kt
clix/src/main/kotlin/**/*.kt
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
clix/src/main/kotlin/**/*.kt: Use Kotlin Coroutines for asynchronous operations
Ensure thread safety for shared mutable state
Write small, pure, composable functions; favor immutability and explicit side effects
Use descriptive names and prefer expression-style functions where clear
Order declarations Public → Internal → Private
Avoid reflection, annotations, and metaprogramming unless necessary
Do not use service locators or singletons (unless absolutely necessary)
No reflection under any circumstances
Use DataStore Preferences for local storage
Files:
clix/src/main/kotlin/so/clix/services/TokenService.ktclix/src/main/kotlin/so/clix/core/Clix.ktclix/src/main/kotlin/so/clix/core/ClixNotification.kt
clix/src/main/kotlin/so/clix/{models,services}/**/*.kt
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
clix/src/main/kotlin/so/clix/{models,services}/**/*.kt: Use kotlinx.serialization for JSON handling
Map between domain models and DTOs at the boundaries
Files:
clix/src/main/kotlin/so/clix/services/TokenService.kt
clix/src/main/kotlin/so/clix/{core,models}/**/*.kt
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Use sealed classes for finite states or results
Files:
clix/src/main/kotlin/so/clix/core/Clix.ktclix/src/main/kotlin/so/clix/core/ClixNotification.kt
clix/src/main/kotlin/so/clix/core/**/*.kt
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
clix/src/main/kotlin/so/clix/core/**/*.kt: Use functional error wrappers (sealed classes) in domain logic
Keep domain logic pure and side-effect-free
Files:
clix/src/main/kotlin/so/clix/core/Clix.ktclix/src/main/kotlin/so/clix/core/ClixNotification.kt
**/*.gradle.kts
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Use Kotlin 2.x as the minimum Kotlin version (configure Kotlin plugin accordingly)
Files:
clix/build.gradle.kts
{build.gradle.kts,settings.gradle.kts,clix/build.gradle.kts,gradle.properties,gradle/wrapper/gradle-wrapper.properties}
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Target Gradle 8.x with Kotlin DSL and JVM 21 toolchain
Files:
clix/build.gradle.kts
{clix/build.gradle.kts,clix/src/main/AndroidManifest.xml}
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Set Android minSdk to API 21 or higher
Files:
clix/build.gradle.kts
{gradle/libs.versions.toml,**/*.gradle.kts}
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Use Firebase via BOM and version catalog
Files:
clix/build.gradle.ktsgradle/libs.versions.toml
{gradle/libs.versions.toml,**/*.gradle.kts,detekt.yml}
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Use ktfmt, detekt, and jacoco via the Gradle version catalog
Files:
clix/build.gradle.ktsgradle/libs.versions.toml
🧠 Learnings (24)
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to {clix/build.gradle.kts,clix/src/main/AndroidManifest.xml} : Set Android minSdk to API 21 or higher
Applied to files:
README.mdclix/build.gradle.ktsgradle/libs.versions.toml
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/** : Follow the specified library source structure under clix/src/main/kotlin/so/clix/(core|models|notification|services|utils)
Applied to files:
README.mdclix/build.gradle.ktsgradle/libs.versions.toml
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/{models,services}/**/*.kt : Use kotlinx.serialization for JSON handling
Applied to files:
README.mdclix/src/test/kotlin/so/clix/services/TokenServiceTest.ktclix/src/main/kotlin/so/clix/services/TokenService.ktgradle/libs.versions.toml
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/{test,androidTest}/kotlin/**/*.kt : Use JUnit4/Kotest for unit tests and AndroidX Test/Robolectric for instrumentation
Applied to files:
README.mdclix/src/test/kotlin/so/clix/services/TokenServiceTest.ktgradle/libs.versions.toml
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Use Kotlin Coroutines for asynchronous operations
Applied to files:
README.mdclix/src/main/kotlin/so/clix/core/Clix.ktclix/build.gradle.ktsclix/src/main/kotlin/so/clix/core/ClixNotification.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/services/**/*.kt : Classes interacting with external services must use Service or Repository suffix
Applied to files:
README.mdclix/src/test/kotlin/so/clix/services/TokenServiceTest.ktclix/src/main/kotlin/so/clix/services/TokenService.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/test/kotlin/so/clix/** : Mirror main source structure for unit tests under clix/src/test/kotlin/so/clix
Applied to files:
README.mdclix/src/test/kotlin/so/clix/services/TokenServiceTest.ktclix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/models/**/*.kt : Keep domain models serialization-agnostic (no framework annotations in core models)
Applied to files:
README.mdclix/src/main/kotlin/so/clix/services/TokenService.ktclix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/utils/**/*.kt : Group utility classes/functions logically under utils (and its subpackages)
Applied to files:
README.mdclix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Do not use service locators or singletons (unless absolutely necessary)
Applied to files:
README.mdclix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/services/**/*.kt : Handle side effects explicitly within repository/service classes
Applied to files:
clix/src/test/kotlin/so/clix/services/TokenServiceTest.ktclix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Use DataStore Preferences for local storage
Applied to files:
clix/src/test/kotlin/so/clix/services/TokenServiceTest.ktclix/src/main/kotlin/so/clix/services/TokenService.ktclix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/{test,androidTest}/kotlin/**/*.kt : Use property-based tests for pure functions where applicable
Applied to files:
clix/src/test/kotlin/so/clix/services/TokenServiceTest.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/models/**/*.kt : Model types use singular, descriptive names (e.g., User, AuthToken)
Applied to files:
clix/src/test/kotlin/so/clix/services/TokenServiceTest.ktclix/src/main/kotlin/so/clix/services/TokenService.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/{models,services}/**/*.kt : Map between domain models and DTOs at the boundaries
Applied to files:
clix/src/test/kotlin/so/clix/services/TokenServiceTest.ktclix/src/main/kotlin/so/clix/services/TokenService.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/{test,androidTest}/kotlin/**/*.kt : Use Stub and Spy patterns via MockK for doubles
Applied to files:
clix/src/test/kotlin/so/clix/services/TokenServiceTest.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Use descriptive names and prefer expression-style functions where clear
Applied to files:
clix/src/main/kotlin/so/clix/services/TokenService.ktclix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Ensure thread safety for shared mutable state
Applied to files:
clix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/core/**/*.kt : Keep domain logic pure and side-effect-free
Applied to files:
clix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Write small, pure, composable functions; favor immutability and explicit side effects
Applied to files:
clix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/{core,models}/**/*.kt : Use sealed classes for finite states or results
Applied to files:
clix/src/main/kotlin/so/clix/core/Clix.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to {build.gradle.kts,settings.gradle.kts,clix/build.gradle.kts,gradle.properties,gradle/wrapper/gradle-wrapper.properties} : Target Gradle 8.x with Kotlin DSL and JVM 21 toolchain
Applied to files:
clix/build.gradle.ktsgradle/libs.versions.toml
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to {gradle/libs.versions.toml,**/*.gradle.kts} : Use Firebase via BOM and version catalog
Applied to files:
clix/build.gradle.ktsgradle/libs.versions.toml
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Use Jetpack Compose 1.x or Android Views where necessary for UI
Applied to files:
gradle/libs.versions.toml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (12)
CHANGELOG.md (1)
7-16: LGTM!The changelog entry clearly documents the behavioral changes for push notification handlers and the internal naming convention improvements, aligning well with the code changes in this PR.
gradle/libs.versions.toml (2)
19-21: LGTM!The lifecycle version entry and structure follow the version catalog conventions correctly.
57-58: LGTM!The
androidx-lifecycle-processlibrary is correctly added with proper version reference to enable foreground state detection.clix/build.gradle.kts (1)
76-76: LGTM!The
lifecycle-processdependency is correctly added to enableProcessLifecycleOwnerfor foreground state detection in notification handling.README.md (1)
22-22: LGTM!The dependency version is correctly updated to 1.3.2 to match the release.
clix/src/main/kotlin/so/clix/core/ClixNotification.kt (3)
7-8: LGTM!The imports for
LifecycleandProcessLifecycleOwnerare correctly added to support foreground state detection.
232-261: Well-structured foreground/background handler routing.The logic correctly routes notifications to the appropriate handler based on app state. Error handling is appropriate: foreground handler failures default to showing the notification, and background handler failures are logged without blocking notification display.
270-277: Code correctly handles cold start edge case; consider adding clarifying comment.
ProcessLifecycleOwnermay not be fully initialized when accessed fromonMessageReceived()during cold starts. The existing try-catch with fallback tofalse(background) appropriately handles this scenario—a safe conservative approach that ensures notifications aren't lost.Adding a brief comment explaining that the exception handling accounts for ProcessLifecycleOwner initialization timing on cold starts would help future maintainers understand this is intentional.
clix/src/main/kotlin/so/clix/core/Clix.kt (4)
40-43: Clean refactoring of internal naming.The rename from
COROUTINE_CONTEXTtocoroutineContextfollows Kotlin naming conventions for properties. Using a dedicatedInitializeLockobject is a good practice for identity-based synchronization, making the lock's purpose explicit.
54-54: LGTM!The
coroutineScopecorrectly references the renamedcoroutineContext.
68-68: LGTM!Using
InitializeLockfor synchronization is clearer and follows best practices.
266-274: LGTM!The internal
initializemethod correctly usesInitializeLockfor synchronization andconfigKeyfor retrieving saved configuration. The double-checked locking pattern is properly implemented.
…on flow - Replace hardcoded Clix config values with JSON-based configuration. - Add `ClixConfig.json.example` for credential setup. - Update `.gitignore` to exclude sensitive config files. - Improve modularity of `ClixConfiguration` with JSON parsing.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
samples/basic-app/src/main/kotlin/so/clix/samples/basic/BasicApplication.kt (1)
29-32: Consider adding error handling for configuration initialization.The
ClixConfiguration.initialize(this)call may throw exceptions during JSON parsing or file I/O (e.g., missingClixConfig.jsonor invalid JSON format). While this is a sample app, adding error handling would demonstrate best practices and provide better developer experience.Apply this diff to add error handling:
- // Initialize ClixConfiguration from JSON file - ClixConfiguration.initialize(this) - - Clix.initialize(this, ClixConfiguration.config) + // Initialize ClixConfiguration from JSON file + try { + ClixConfiguration.initialize(this) + Clix.initialize(this, ClixConfiguration.config) + } catch (e: Exception) { + Log.e("BasicApplication", "Failed to initialize configuration", e) + // Consider providing fallback configuration or showing user-friendly error + }samples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt (2)
14-14: Consider documenting the hard-coded DEBUG log level.The
logLevelfield is hard-coded toDEBUGand overrides anylogLevelvalue from the JSON configuration (line 25). This might be confusing for developers examining the sample. Consider adding a comment explaining this override behavior.Apply this diff to add clarifying documentation:
- private val logLevel: ClixLogLevel = ClixLogLevel.DEBUG + // Hard-coded DEBUG level for sample app; overrides JSON config logLevel + private val logLevel: ClixLogLevel = ClixLogLevel.DEBUG
19-26: Consider using explicit resource management for asset loading.While
readText()should handle resource cleanup, explicitly usinguse()would make resource management more explicit and safer.Apply this diff to use explicit resource management:
fun initialize(context: Context) { - config = - json - .decodeFromString<ClixConfig>( - context.assets.open("ClixConfig.json").bufferedReader().readText() - ) - .copy(logLevel = logLevel) + config = context.assets.open("ClixConfig.json").use { inputStream -> + json + .decodeFromString<ClixConfig>( + inputStream.bufferedReader().readText() + ) + .copy(logLevel = logLevel) + } }Note: Error handling for this initialization is discussed in the
BasicApplication.ktreview.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.gitignore(1 hunks)samples/basic-app/README.md(1 hunks)samples/basic-app/build.gradle.kts(2 hunks)samples/basic-app/src/main/assets/ClixConfig.json.example(1 hunks)samples/basic-app/src/main/kotlin/so/clix/samples/basic/BasicApplication.kt(1 hunks)samples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt(1 hunks)samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.kt(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- samples/basic-app/src/main/assets/ClixConfig.json.example
- .gitignore
- samples/basic-app/README.md
🧰 Additional context used
📓 Path-based instructions (4)
samples/**
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Place example applications under samples/
Files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/build.gradle.ktssamples/basic-app/src/main/kotlin/so/clix/samples/basic/BasicApplication.ktsamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
**/*.gradle.kts
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Use Kotlin 2.x as the minimum Kotlin version (configure Kotlin plugin accordingly)
Files:
samples/basic-app/build.gradle.kts
{gradle/libs.versions.toml,**/*.gradle.kts}
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Use Firebase via BOM and version catalog
Files:
samples/basic-app/build.gradle.kts
{gradle/libs.versions.toml,**/*.gradle.kts,detekt.yml}
📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)
Use ktfmt, detekt, and jacoco via the Gradle version catalog
Files:
samples/basic-app/build.gradle.kts
🧠 Learnings (21)
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Use descriptive names and prefer expression-style functions where clear
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/models/**/*.kt : Define domain models as immutable data classes
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/build.gradle.ktssamples/basic-app/src/main/kotlin/so/clix/samples/basic/BasicApplication.ktsamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Use DataStore Preferences for local storage
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/models/**/*.kt : Keep domain models serialization-agnostic (no framework annotations in core models)
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/build.gradle.ktssamples/basic-app/src/main/kotlin/so/clix/samples/basic/BasicApplication.ktsamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Write small, pure, composable functions; favor immutability and explicit side effects
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/build.gradle.kts
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/{models,services}/**/*.kt : Use kotlinx.serialization for JSON handling
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/build.gradle.ktssamples/basic-app/src/main/kotlin/so/clix/samples/basic/BasicApplication.ktsamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/core/**/*.kt : Keep domain logic pure and side-effect-free
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Avoid reflection, annotations, and metaprogramming unless necessary
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/build.gradle.ktssamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to {clix/build.gradle.kts,clix/src/main/AndroidManifest.xml} : Set Android minSdk to API 21 or higher
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/build.gradle.ktssamples/basic-app/src/main/kotlin/so/clix/samples/basic/BasicApplication.ktsamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Do not use service locators or singletons (unless absolutely necessary)
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.ktsamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to {build.gradle.kts,settings.gradle.kts,clix/build.gradle.kts,gradle.properties,gradle/wrapper/gradle-wrapper.properties} : Target Gradle 8.x with Kotlin DSL and JVM 21 toolchain
Applied to files:
samples/basic-app/build.gradle.kts
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to {gradle/libs.versions.toml,**/*.gradle.kts,detekt.yml} : Use ktfmt, detekt, and jacoco via the Gradle version catalog
Applied to files:
samples/basic-app/build.gradle.kts
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to **/*.gradle.kts : Use Kotlin 2.x as the minimum Kotlin version (configure Kotlin plugin accordingly)
Applied to files:
samples/basic-app/build.gradle.kts
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/{test,androidTest}/kotlin/**/*.kt : Use JUnit4/Kotest for unit tests and AndroidX Test/Robolectric for instrumentation
Applied to files:
samples/basic-app/build.gradle.kts
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to {gradle/libs.versions.toml,**/*.gradle.kts} : Use Firebase via BOM and version catalog
Applied to files:
samples/basic-app/build.gradle.kts
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/** : Follow the specified library source structure under clix/src/main/kotlin/so/clix/(core|models|notification|services|utils)
Applied to files:
samples/basic-app/build.gradle.kts
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Use Kotlin Coroutines for asynchronous operations
Applied to files:
samples/basic-app/build.gradle.kts
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/test/kotlin/so/clix/** : Mirror main source structure for unit tests under clix/src/test/kotlin/so/clix
Applied to files:
samples/basic-app/build.gradle.ktssamples/basic-app/src/main/kotlin/so/clix/samples/basic/BasicApplication.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/utils/**/*.kt : Group utility classes/functions logically under utils (and its subpackages)
Applied to files:
samples/basic-app/build.gradle.ktssamples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/so/clix/{models,services}/**/*.kt : Map between domain models and DTOs at the boundaries
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
📚 Learning: 2025-10-15T05:36:01.516Z
Learnt from: CR
Repo: clix-so/clix-android-sdk PR: 0
File: .cursor/rules/guidelines.mdc:0-0
Timestamp: 2025-10-15T05:36:01.516Z
Learning: Applies to clix/src/main/kotlin/**/*.kt : Order declarations Public → Internal → Private
Applied to files:
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (5)
samples/basic-app/build.gradle.kts (2)
48-48: LGTM!The kotlinx.serialization.json dependency is correctly added via the version catalog and aligns with the project's JSON handling requirements.
4-4: Upgrade Kotlin version to 2.x minimum as required by coding guidelines.The Kotlin version in
gradle/libs.versions.tomlis set to 1.9.25, which does not meet the required minimum of Kotlin 2.x for**/*.gradle.ktsfiles. Update the version catalog accordingly, which will also update the kotlin-serialization plugin since it references the Kotlin version.⛔ Skipped due to learnings
Learnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to **/*.gradle.kts : Use Kotlin 2.x as the minimum Kotlin version (configure Kotlin plugin accordingly)Learnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to {gradle/libs.versions.toml,**/*.gradle.kts,detekt.yml} : Use ktfmt, detekt, and jacoco via the Gradle version catalogLearnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to clix/src/main/kotlin/so/clix/{models,services}/**/*.kt : Use kotlinx.serialization for JSON handlingLearnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to {build.gradle.kts,settings.gradle.kts,clix/build.gradle.kts,gradle.properties,gradle/wrapper/gradle-wrapper.properties} : Target Gradle 8.x with Kotlin DSL and JVM 21 toolchainLearnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to clix/src/main/kotlin/so/clix/models/**/*.kt : Keep domain models serialization-agnostic (no framework annotations in core models)Learnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to {gradle/libs.versions.toml,**/*.gradle.kts} : Use Firebase via BOM and version catalogLearnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to clix/src/main/kotlin/**/*.kt : Avoid reflection, annotations, and metaprogramming unless necessaryLearnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to {clix/build.gradle.kts,clix/src/main/AndroidManifest.xml} : Set Android minSdk to API 21 or higherLearnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to clix/src/{test,androidTest}/kotlin/**/*.kt : Use JUnit4/Kotest for unit tests and AndroidX Test/Robolectric for instrumentationLearnt from: CR Repo: clix-so/clix-android-sdk PR: 0 File: .cursor/rules/guidelines.mdc:0-0 Timestamp: 2025-10-15T05:36:01.516Z Learning: Applies to clix/src/main/kotlin/**/*.kt : No reflection under any circumstancessamples/basic-app/src/main/kotlin/so/clix/samples/basic/ContentView.kt (1)
116-116: LGTM!The migration from static constants to property-based configuration access is clean and correct. The initialization order is safe since
ClixConfiguration.initialize(context)is called inBasicApplication.onCreatebefore the UI is composed.Also applies to: 120-120
samples/basic-app/src/main/kotlin/so/clix/samples/basic/ClixConfiguration.kt (2)
9-12: LGTM!The Json configuration is appropriate for loading configuration files. The
ignoreUnknownKeys = truesetting enables forward compatibility, andisLenient = trueprovides flexibility for the sample app.
16-17: LGTM!The
lateinit varwith private setter is appropriate for deferred initialization. The initialization order ensures this property is set before any external access.
onMessageto trigger only in the foreground and introducedonBackgroundMessagefor handling background notifications.Summary by CodeRabbit
Changed
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.