-
Notifications
You must be signed in to change notification settings - Fork 15
Feature/firebase analytics #3004
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
9498448
Add Firebase analytics interface and Android impl
StylianosGakis 773972e
Add simple tracking on current destination
StylianosGakis f9ceb8d
Add screen class in firebase analytics screen tracking
StylianosGakis 2dfdf25
download latest google-services.json for debug app
StylianosGakis 188cf71
Add parameter extracton on screen tracking
StylianosGakis 5875d0e
Add `ScreenParameterExtractor` tests
StylianosGakis f47f300
Run lint
StylianosGakis a4aa077
Run ktlint
StylianosGakis ae95e45
Merge branch 'chore/cleanup-prod-or-demo-providers' into feature/fire…
StylianosGakis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
app/app/src/main/kotlin/com/hedvig/android/app/navigation/ScreenParameterExtractor.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| package com.hedvig.android.app.navigation | ||
|
|
||
| import com.hedvig.android.core.common.di.AppScope | ||
| import com.hedvig.android.navigation.common.HedvigNavKey | ||
| import com.hedvig.android.navigation.common.TrackedScreen | ||
| import com.hedvig.android.navigation.compose.merge | ||
| import dev.zacsweers.metro.Inject | ||
| import dev.zacsweers.metro.SingleIn | ||
| import kotlinx.serialization.PolymorphicSerializer | ||
| import kotlinx.serialization.json.Json | ||
| import kotlinx.serialization.json.JsonElement | ||
| import kotlinx.serialization.json.JsonNull | ||
| import kotlinx.serialization.json.JsonObject | ||
| import kotlinx.serialization.json.JsonPrimitive | ||
| import kotlinx.serialization.json.booleanOrNull | ||
| import kotlinx.serialization.json.doubleOrNull | ||
| import kotlinx.serialization.json.longOrNull | ||
| import kotlinx.serialization.modules.SerializersModule | ||
|
|
||
| /** | ||
| * Derives the analytics parameters attached to a destination's `screen_view`. By default it reflects | ||
| * the key's own [kotlinx.serialization]-serialized properties (every `@Serializable` `val` becomes a | ||
| * parameter), reusing the same merged [SerializersModule]s that persist the back stack — so any key | ||
| * that survives process death automatically has reportable parameters with no per-screen wiring. A key | ||
| * may instead implement [TrackedScreen] to take over entirely. | ||
| * | ||
| * Parameters ride along the single `screen_view` event keyed by screen name, so they act as breakdown | ||
| * dimensions rather than fragmenting a screen into separate entries. | ||
| */ | ||
| @SingleIn(AppScope::class) | ||
| @Inject | ||
| internal class ScreenParameterExtractor( | ||
| serializersModules: Set<SerializersModule>, | ||
| ) { | ||
| private val json = Json { | ||
| serializersModule = serializersModules.merge() | ||
| encodeDefaults = true | ||
| } | ||
|
|
||
| fun parametersFor(destination: HedvigNavKey): Map<String, Any?> { | ||
| if (destination is TrackedScreen) { | ||
| return destination.screenParameters | ||
| } | ||
| val element = runCatching { | ||
| json.encodeToJsonElement(PolymorphicSerializer(HedvigNavKey::class), destination) | ||
| }.getOrNull() as? JsonObject ?: return emptyMap() | ||
| return element | ||
| .filterKeys { it != CLASS_DISCRIMINATOR } | ||
| .mapValues { (_, value) -> value.toPrimitiveOrNull() } | ||
| } | ||
|
|
||
| // The default polymorphic discriminator kotlinx.serialization writes to identify the concrete key | ||
| // type; it duplicates the screen name/class, so it is dropped from the reported parameters. | ||
| private companion object { | ||
| const val CLASS_DISCRIMINATOR = "type" | ||
| } | ||
| } | ||
|
|
||
| private fun JsonElement.toPrimitiveOrNull(): Any? = when (this) { | ||
| is JsonNull -> null | ||
| is JsonPrimitive -> if (isString) content else (booleanOrNull ?: longOrNull ?: doubleOrNull ?: content) | ||
| else -> toString() | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
app/app/src/test/kotlin/com/hedvig/android/app/navigation/ScreenParameterExtractorTest.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| package com.hedvig.android.app.navigation | ||
|
|
||
| import assertk.assertThat | ||
| import assertk.assertions.isEmpty | ||
| import assertk.assertions.isEqualTo | ||
| import com.hedvig.android.navigation.common.HedvigNavKey | ||
| import com.hedvig.android.navigation.common.TrackedScreen | ||
| import kotlinx.serialization.Serializable | ||
| import kotlinx.serialization.modules.SerializersModule | ||
| import kotlinx.serialization.modules.polymorphic | ||
| import kotlinx.serialization.modules.subclass | ||
| import org.junit.Test | ||
|
|
||
| internal class ScreenParameterExtractorTest { | ||
| private val extractor = ScreenParameterExtractor( | ||
| setOf( | ||
| SerializersModule { | ||
| polymorphic(HedvigNavKey::class) { | ||
| subclass(SimpleKey::class) | ||
| subclass(EmptyKey::class) | ||
| subclass(NullableKey::class) | ||
| subclass(NestedKey::class) | ||
| subclass(OverridingKey::class) | ||
| } | ||
| }, | ||
| ), | ||
| ) | ||
|
|
||
| @Test | ||
| fun `primitive properties are flattened and coerced to Firebase-compatible types`() { | ||
| val params = extractor.parametersFor(SimpleKey(id = "abc", count = 42, enabled = true)) | ||
|
|
||
| assertThat(params).isEqualTo( | ||
| mapOf<String, Any?>( | ||
| "id" to "abc", | ||
| "count" to 42L, // Int coerces to Long | ||
| "enabled" to true, | ||
| ), | ||
| ) | ||
| } | ||
|
|
||
| @Test | ||
| fun `the polymorphic type discriminator is dropped`() { | ||
| val params = extractor.parametersFor(EmptyKey) | ||
|
|
||
| assertThat(params).isEmpty() | ||
| } | ||
|
|
||
| @Test | ||
| fun `null-valued properties are preserved as null`() { | ||
| val params = extractor.parametersFor(NullableKey(maybe = null)) | ||
|
|
||
| assertThat(params).isEqualTo(mapOf<String, Any?>("maybe" to null)) | ||
| } | ||
|
|
||
| @Test | ||
| fun `nested objects fall back to their JSON string`() { | ||
| val params = extractor.parametersFor(NestedKey(inner = Inner(a = "x"))) | ||
|
|
||
| assertThat(params).isEqualTo(mapOf<String, Any?>("inner" to """{"a":"x"}""")) | ||
| } | ||
|
|
||
| @Test | ||
| fun `a TrackedScreen takes over with its own parameters, ignoring serialized shape`() { | ||
| val params = extractor.parametersFor(OverridingKey(secret = "should-not-leak")) | ||
|
|
||
| assertThat(params).isEqualTo(mapOf<String, Any?>("custom" to "value")) | ||
| } | ||
| } | ||
|
|
||
| @Serializable | ||
| private data class SimpleKey(val id: String, val count: Int, val enabled: Boolean) : HedvigNavKey | ||
|
|
||
| @Serializable | ||
| private data object EmptyKey : HedvigNavKey | ||
|
|
||
| @Serializable | ||
| private data class NullableKey(val maybe: String?) : HedvigNavKey | ||
|
|
||
| @Serializable | ||
| private data class NestedKey(val inner: Inner) : HedvigNavKey | ||
|
|
||
| @Serializable | ||
| private data class Inner(val a: String) | ||
|
|
||
| @Serializable | ||
| private data class OverridingKey(val secret: String) : HedvigNavKey, TrackedScreen { | ||
| override val screenParameters: Map<String, Any?> | ||
| get() = mapOf("custom" to "value") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔥