amplitude / Amplitude-Android

Native Android SDK for Amplitude
MIT License
164 stars 90 forks source link

General enums in Ampli #383

Closed kataRebuy closed 1 year ago

kataRebuy commented 1 year ago

Summary

Currently, in Amplitude Data, every event has a separate enum class when generating the Ampli.kt file, even though it is configured as the same event property on amplitude.

Motivations

For example, using the same ScreenName enum for all the events so if I track something from a screen I wouldn't have to use 10 different enums for 10 separate events.

justin-fiedler commented 1 year ago

Hi @kataRebuy thanks for choosing Amplitude and using Ampli!

Unfortunately creating shared enums is not as straight forward as it seems. It is possible for multiple events to have Properties with the same names but different values. We decided to avoid conflicts by nesting each Enum in it's parent Event. The hope was that it is easy to know what value you need for a given Event by using it's nested enums, even if it is verbose.

We could likely consolidate by checking for shared schema's and creating shared Enums for those. However I can imagine that leading to other issues such as having to support both shared and nested enums. I think this could make it confusing to know which Enum is needed for each Event.

Would love to hear your feedback.

Thanks!

class EventWithEnumTypes private constructor(
    eventProperties: Map<String, Any?>?,
    options: EventOptions? = null
) : Event<EventWithEnumTypes>("Event With Enum Types", eventProperties, options, ::EventWithEnumTypes) {
    constructor(requiredEnum: RequiredEnum) : this(mapOf(
        "required enum" to requiredEnum.value
    ), null as EventOptions?)

    enum class RequiredEnum(val value: String) {
        REQUIRED_ENUM_1("required enum 1"),
        REQUIRED_ENUM_2("required enum 2")
    }
}

class Event2WithEnumTypes private constructor(
    eventProperties: Map<String, Any?>?,
    options: EventOptions? = null
) : Event<Event2WithEnumTypes>("Event2 With Enum Types", eventProperties, options, ::Event2WithEnumTypes) {
    constructor(requiredEnum: RequiredEnum) : this(mapOf(
        "required enum" to requiredEnum.value
    ), null as EventOptions?)

    enum class RequiredEnum(val value: String) {
        ENUM_1("enum 1"),
        ENUM_2("enum 2")
    }
}