https://www.growthbook.io/ logo
Join Slack
Powered by
# sdk-kotlin
  • b

    brief-honey-45610

    09/21/2023, 4:04 AM
    set the channel description: Ask questions here related to the Kotlin SDK.
  • h

    hundreds-thailand-97888

    09/29/2023, 2:19 PM
    Hi 👋 I'm working on integrating the kotlin SDK into our app. To begin with I created a single feature flag, and the SDK was initializing correctly and I was able to get the feature flag value. Then I created an experiment with different variants for that feature flag, and now the SDK initialization fails with this message:
    Copy code
    Fields [name, passthrough] are required for type with serial name 'com.sdk.growthbook.Utils.GBVariationMeta', but they were missing at path: $.features['my-feature'].rules[0].meta[0]
    Is there some configuration I could be missing, or could this be a problem within the SDK? I am using version 1.1.38
    b
    • 2
    • 4
  • f

    few-cartoon-95517

    11/14/2023, 5:00 PM
    Hi guys! I am encountering an issue with Kotlin SDK for Android. When filling in the names of splitting groups, I receive the group names enclosed in quotes (e.g., "group_name") in the callback. This issue seems to occur only in Android applications. I suspect it might be related to how the SDK processes attribute and experiment data in the Android environment. Could you please help me understand why this is happening and how to resolve it? Are there any specific implementation details of the SDK on Android that I should be aware of? Thank you for your assistance.
    b
    a
    • 3
    • 2
  • b

    brief-honey-45610

    01/10/2024, 4:48 PM
    Hi, how do we get the variant name (not variant id) from the Java/Kotlin SDK?
    🤔 1
  • a

    ancient-car-96302

    01/10/2024, 6:57 PM
    @important-zebra-55422
  • i

    important-zebra-55422

    01/10/2024, 7:46 PM
    Hi @ancient-car-96302 I don't think we are getting values from
    name
    etc. @nice-book-34304 our android developer is here. Kenji, thanks for coming in and if you could clarify what we see, that'd be great.
  • a

    ancient-car-96302

    01/10/2024, 7:49 PM
    Hello @nice-book-34304! Is trackingCallback being called for your case?
    n
    f
    • 3
    • 24
  • f

    fast-cpu-81722

    01/17/2024, 8:54 PM
    Hello! I've integrated GrowthBook features on my app (Android) and so far so good but I'm having an issue with the first app install, I'm trying to get a feature on the login screen (the first screen in the app) and
    growthBookSDK._feature()_
    returns null. If I kill the app and start again, I'm getting the correct value. I'm guessing that I'm trying to get the feature before Growthbook fetches it from the server.
    r
    a
    • 3
    • 10
  • g

    gentle-glass-72054

    02/22/2024, 8:48 AM
    Hey folks, I'm currently evaluating GrowthBook for the company that I work at. I'm making a sample app to test different feature values. What is the appropriate value type that I should use for
    Long
    ? I tried using the
    number
    type in the GB dashboard, but it sends the value back as an
    Int
    instead.
    a
    • 2
    • 15
  • b

    brief-honey-45610

    03/14/2024, 3:35 PM
    Hi @ancient-car-96302 👋🏻 I have a quick question for you, please — Does the Java/Kotlin SDK support reading flags from an overridden local datasource?
    a
    • 2
    • 11
  • b

    brief-honey-45610

    03/18/2024, 7:42 PM
    Hi again @ancient-car-96302. I'm asking another question on behalf of a user. What is the difference between the Kotlin and Java SDKs? it looks like the Kotlin SDK works on a JVM service, so they were confused why there are two different SDKs.
    a
    • 2
    • 2
  • f

    fast-cpu-81722

    03/20/2024, 4:34 PM
    Hello, we are using the
    trackingCallback
    to logs experiment view. Looking at our logs we are seeing event being logged when the application is in background and at random hours. I was not able to reproduce and from the testing i have done, the
    trackingCallback
    is only triggered the first time we get a feature. Any idea what would cause this issue?
    a
    • 2
    • 6
  • p

    plain-pharmacist-9564

    05/31/2024, 3:08 PM
    Cross posting from the main channel: Multiple Assignment Events from Kotlin SDK Hey 👋 We are currently evaluating GrowthBook in our mobile app and were wondering if having multiple assignment events per user and experiment is expected? The
    trackingCallback
    (in initialize https://docs.growthbook.io/lib/kotlin) is called every first time a feature flag is “requested” from the sdk, killing the app and restarting will trigger a new callback call and send a new assignment event to our data warehouse. I assume we can later on just run a
    min(timestamp)
    on the assignment events, but I would like to double check that this is expected 😊
    a
    • 2
    • 1
  • d

    dazzling-answer-34446

    07/02/2024, 4:55 PM
    Hi folks, When looking at the experiment name as part of the
    trackingCallback
    - I notice it always comes back as
    null
    . Am I correct is expecting this to be the name we set for the experiment on the portal? 🤔
    a
    h
    +2
    • 5
    • 31
  • f

    flaky-noon-11399

    10/08/2024, 11:47 AM
    Hey Team, in the Node.js SDK a customer has taken the approach of caching and serving the Growthbook feature file themselves from their own CDN as described here. Is there a way to achieve the same in Kotlin?
    a
    • 2
    • 8
  • f

    flaky-noon-11399

    10/11/2024, 8:18 AM
    Hey Team, a customer is facing an issue with a null featureResult response, please can you TAL? He wrote: Hi GrowthBook team! I have been working on the GrowthBook integration with our Android app, and I had some issues when using the Kotlin SDK. I get the trackingCallback called correctly with the experimentResult, but the featureResult does not contain that information. You can find my integration here: https://gist.github.com/albertoastiazaran-qz/2925e1c9d4383ae31d3b9db03aa51d64 And the logs printed out here: https://gist.github.com/albertoastiazaran-qz/2a350c3454b40cf3b9499924f90fde30 You can see that the trackingCallback gets a valid experimentResult with value=true, but the featureResult has value=null and source = unknownFeature. Looking at GrowthBook's codebase, I don't see anything glaringly wrong. We actually return experimentResult pretty soon after evaluating the experiment, so there's not many places where could have thrown an exception: GBFeatureEvaluator.kt. I have a simple boolean feature flag and an experiment with a few filters. CC @freezing-postman-69602 @ancient-car-96302
    a
    • 2
    • 8
  • f

    flaky-noon-11399

    10/31/2024, 12:52 PM
    Hey Team, a customer is facing a blocker with overriding a feature value during QA. They write "I've tried the following, but I still get the feature evaluated to false.
    Copy code
    growthBookSDK.setForcedFeatures(mapOf("my_feature" to true))
    I also tried setting
    QAMode
    to true, but I think that controls
    forcedExperiments
    and not
    forcedFeatures
    ?"
    Is there anything missing from their config to override the value?
    m
    c
    • 3
    • 5
  • b

    brief-honey-45610

    11/25/2024, 8:02 PM
    Hi folks 👋🏻 We recently heard from an Enterprise customer about an undesired change that was made to the Kotlin SDK. Could someone please take a look? Thanks!
    There was a recent change to the kotlin SDK where they made some attributes in
    GBError
    private. We depended on that to log GrowthBook failures, so I'm hoping it can be made public again. I left a comment in the PR here: https://github.com/growthbook/growthbook-kotlin/pull/149/files#r1857236623.
    m
    c
    f
    • 4
    • 4
  • o

    orange-book-30667

    12/17/2024, 9:54 AM
    Hey Team, what is it going on with the tags and releases? I'm confused 😵‍💫 I was getting crazy understanding the change of GBFeatureResult returning type and looking a release notes made even more confused. Now I found a changelog section at the end of the home page but above in the page it keeps referring to
    Any?
    . Please help me understand
    a
    s
    f
    • 4
    • 15
  • f

    fresh-guitar-29838

    01/17/2025, 7:20 PM
    Hi! Are there any plans to further reduce the use of
    Any
    in the SDK? It is often used unnecessarily, leading to loss of type safety. For example: here, here, and many more.
    c
    a
    • 3
    • 6
  • o

    orange-book-30667

    01/28/2025, 1:30 PM
    @ancient-car-96302 why did you changed
    GBFeature.defaultValue
    to
    internal
    in your recent alpha?
    a
    • 2
    • 12
  • a

    ancient-car-96302

    02/04/2025, 10:31 AM
    Attention! This request also leads to major version increase
  • f

    fresh-guitar-29838

    02/05/2025, 1:02 AM
    Hi team, I'm just upgrading my app to GB v2.0.0, and I ran into some issues. Can we rename one of these two functions into something different? The latest update is breaking our tests, since inline functions can't be mocked. When I try to mock the first method, sometimes it calls the second one instead, and it ends up calling the actual internal implementation of GrowthBookSDK instead of the mock.
    a
    • 2
    • 14
  • a

    ancient-car-96302

    02/26/2025, 10:03 AM
    Hello! v3.0.0-alpha appeared on Maven. This is the example of how to define user attributes in v3.0.0-alpha:
    🙌 2
    • 1
    • 1
  • f

    fresh-guitar-29838

    03/19/2025, 11:19 PM
    Hello! GrowthBook
    forcedFeatures
    broke in the latest version of the kotlin SDK.
    forcedFeatures
    recently changed from
    Map<String, Any>
    to
    Map<String, GBValue>
    . The problem is that
    GBFeatureEvaluator
    wasn't updated, and it's still using Any here. That means than when actually evaluating a forced feature, it's expecting a JsonElement instead of a GBValue over here. Instead of returning the forced value, it instead returns
    GBValue.Unknown
    . Further, there is another bug where
    GBValue.Unknown
    is parsed as
    isOn=true
    , instead of false. That is happening over here. The default should be
    false
    , not
    true
    , so this logic is incorrect. You can see where I printed out the `GBFeatureResult`:
    Copy code
    GBFeatureResult(gbValue=Unknown, on=true, off=false, source=override, experiment=null, experimentResult=null)
    Thank you!
    a
    b
    • 3
    • 4
  • o

    orange-book-30667

    03/27/2025, 11:21 AM
    Hello 👋, I can see that
    trackingCallback
    is called every time a feature is evaluated, even if there seems to be some code that's meant to prevent it (com.sdk.growthbook.evaluators.GBExperimentHelper). If I'm not mistaken seems like the object or the context is created at every evaluation making the function pointless. Can somebody take a look at it? I'm still running version 2.0.0 but 3.1.0 seems to be affected the same.
    🤔 1
    👀 1
    c
    a
    • 3
    • 5
  • f

    flaky-noon-11399

    05/12/2025, 10:55 AM
    Hi Team, a customer is facing an error when enabling autoRefreshFeatures() in the Android SDK. From what I can see this may be related to a URL malfunction and I did notice a double // before the sdk param of the URL (see error). They are using GBSDKBuilder and have confirmed that they have not put a / before the sdk (clientKey). Attached is their query and assisted information. Is there anything that could be causing the double // ?
    a
    c
    s
    • 4
    • 23
  • b

    brave-controller-43565

    05/22/2025, 10:18 AM
    Hi Team, im trying to force some feature, the first think i expected is that `setForcedVariations`could make that but no, the next i checked is that to force feature I need to overrwrite a variable in GrowthBookSDK object , this variable exactly.
    Copy code
    /* visible for test */ var forcedFeatures: Map<String, GBValue> = emptyMap()
    Then i checked inside de sdk , that in the
    evaluateFeature
    function it is happening that
    Copy code
    /**
     * Global override
     */
    if (forcedFeature.containsKey(featureKey)) {
        if (evaluationContext.loggingEnabled) {
            println("Global override for forced feature with key: $featureKey and value ${forcedFeature[featureKey]}")
        }
        return prepareResult(
            featureKey = featureKey,
            gbValue = forcedFeature[featureKey]?.let(GBValue::from),
            source = GBFeatureSource.override,
        )
    }
    and the most important thing.
    Copy code
    gbValue = forcedFeature[featureKey]?.let(GBValue::from),
    This is getting me an unexpected result becasue de function
    from
    makes that
    Copy code
    internal fun from(anyObj: Any): GBValue =
        when(anyObj) {
            is Boolean -> GBBoolean(anyObj)
            is String -> GBString(anyObj)
            is Number -> GBNumber(anyObj)
            else -> Unknown
        }
    But my forcedFeature map never gonna be fine, because is
    Map<String, GBValue>
    and always is gonna go dor the else case. Is this a bug or what im doing bad at time of force an experiment result. Also you can tell me how works setForcedVariation, because i putted the experiment key or feature key and 0 or 1 but is not working
    a
    • 2
    • 44
  • b

    brave-controller-43565

    05/22/2025, 10:55 AM
    Also i faced that setForcedVariations only works when us
    run(experiment: GBExperiment)
    but usually in my project we use
    feature(id: String)
    Ok , i faced that its running evalExperiment also, forget that :D
    😅 1
  • f

    flaky-noon-11399

    07/18/2025, 2:29 PM
    Hi Team, we have an Enterprise customer who using the Kotlin and Java SDK and has noticed that the same user is being bucketed in different variations on each SDK when maintaining a consistent growthbook_id identifier on each. They have asked if there is a way to ensure parity and how the hashing works for each SDK. Please, can you review their testing results (below) and confirm if there is a solution for this? We also had something similar mentioned in the #C05T9EY0UKC channel here, where this PR was released for it, is it the same thing happening in Kotlin perhaps? Customer testing: I’ve recently integrated the GrowthBook Java SDK (v 0.9.91) into our Android app and ran some tests to compare its behavior with the current Android/Kotlin SDK (v 1.1.41) implementation. I noticed a discrepancy in how the two SDKs bucket the same user, even when using identical attributes. TL;DR: The same user, identified by the
    growthbook_id
    , is being assigned to different variations by the two SDKs. After initializing both SDKs, I set up the same attributes and captured the
    ExperimentResult
    logs. Here’s a representative comparison: Android SDK (current implementation):
    Copy code
    Experiment ab-app-multiple__double-points result: {"id":"doublePoints","enabled":true,"configuration":{...}}
    hashAttribute: growthbook_id -> 7662e35d-57a9-49bd-a0b6-db2268ad0439  
    bucket: -> null  
    variationId: -> 1
    J*ava SDK (our new integration):*
    Copy code
    Experiment ab-app-multiple__double-points result: {id=doublePoints, enabled=false}  
    hashAttribute: growthbook_id -> 7662e35d-57a9-49bd-a0b6-db2268ad0439  
    bucket: -> 0.4606  
    variationId: -> 0
    Both SDKs correctly pick up the same
    growthbook_id
    , but produce different bucketing outcomes: • The Android SDK consistently returns
    null
    for the bucket but assigns the user to variation
    1
    (variant). • The Java SDK returns a valid bucket (
    0.4606
    ) and assigns the user to variation
    0
    (control). These tests were performed on the same device, without using any proxy or intermediate layer—just a direct call to GrowthBook apiHost with the same apiKey. This suggests a potential inconsistency in how the SDKs compute the hash/bucket based on the provided attribute. To further investigate, I tested other
    growthbook_id
    values and observed inconsistent results: • `7662e35d-57a9-49bd-a0b6-db2268ad0439`: Android SDK → variant, Java SDK → control • `1a2f94b5-667e-4a7d-9823-8d4bf611085c`: Android SDK → control, Java SDK → variant • `23aa8888-97fe-4c57-9a57-f3517fa1f89c`: Android SDK → variant, Java SDK → control • `3145ff6a-2148-48cb-b032-7f1892380a17`: Android SDK → variant, Java SDK → control • `07b18ce4-6311-42ae-9bd9-68cd5e2623fc`: Android SDK → variant, Java SDK → variant Given that the same inputs yield different results, this seems like something internal to how each SDK handles hashing and bucketing. Do you happen to know if there’s a known difference in hashing logic between the Java and Android SDKs? Or is there a recommended way to ensure parity? Any insights or suggestions on how to approach this would be greatly appreciated!
    c
    a
    • 3
    • 13