Code Monkey home page Code Monkey logo

klaviyo-android-sdk's People

Contributors

ajaysubra avatar evan-masseau avatar jenren-tech avatar jordan-griffin avatar kennyklaviyo avatar ndurell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

isabella232

klaviyo-android-sdk's Issues

Klaviyo.setPushToken() may cause app crash

Description

We have observed a significant number of IllegalThreadStateException exceptions for our app in the Google Play Store Console. Upon examining the stack trace, it appears that these exceptions are triggered by the invocation of Klaviyo.setPushToken().

Checklist

  • I have determined whether this bug is also reproducible in a vanilla Android project
  • If possible, I've reproduced the issue using the main branch of this package.
  • This issue hasn't been addressed in an existing GitHub issue or pull request.

Expected behavior

The app run normally and no crash

Actual behavior

The app performs well in most cases, but on some case, it may lead to crashes (about 1% probability).

Steps to reproduce

1、Integrate the SDK within the app and initialize it in the Application class. Code snippet as below:
     
Klaviyo.initialize(“klaviyo_public_key”, context)
FirebaseMessaging.getInstance().token.addOnSuccessListener { token ->
    Klaviyo.setPushToken(token)
}

2、Configure the KlaviyoPushService in the manifest。
3、Run the app, the app may throw IllegalThreadStateException. The stack trace as below.

Fatal Exception: java.lang.IllegalThreadStateException:
       at java.lang.Thread.start(Thread.java:872)
       at com.klaviyo.analytics.networking.KlaviyoApiClient.initBatch(KlaviyoApiClient.kt:205)
       at com.klaviyo.analytics.networking.KlaviyoApiClient.enqueueRequest(KlaviyoApiClient.kt:113)
       at com.klaviyo.analytics.networking.KlaviyoApiClient.enqueuePushToken(KlaviyoApiClient.kt:81)
       at com.klaviyo.analytics.Klaviyo.setPushToken(Klaviyo.kt:153)
       at com.klaviyo.pushFcm.KlaviyoPushService.onNewToken(KlaviyoPushService.kt:29)
       at com.google.firebase.messaging.FirebaseMessagingService.handleIntent(FirebaseMessagingService.java:163)
       at com.google.firebase.messaging.EnhancedIntentService.lambda$processIntent$0(EnhancedIntentService.java:78)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
       at com.google.android.gms.common.util.concurrent.zza.run(com.google.android.gms:play-services-basement@@18.1.0:2)
       at java.lang.Thread.run(Thread.java:923)

or 

Fatal Exception: java.lang.IllegalThreadStateException:
       at java.lang.Thread.start(Thread.java:960)
       at com.klaviyo.analytics.networking.KlaviyoApiClient.initBatch(KlaviyoApiClient.kt:205)
       at com.klaviyo.analytics.networking.KlaviyoApiClient.enqueueRequest(KlaviyoApiClient.kt:113)
       at com.klaviyo.analytics.networking.KlaviyoApiClient.enqueuePushToken(KlaviyoApiClient.kt:81)
       at com.klaviyo.analytics.Klaviyo.setPushToken(Klaviyo.kt:153)
       at com.myapp.app.startup.KlaviyoInitializer.create$lambda-0(KlaviyoInitializer.kt:17)
       at com.google.android.gms.tasks.zzm.run(com.google.android.gms:play-services-tasks@@18.0.1:1)
       at android.os.Handler.handleCallback(Handler.java:942)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loopOnce(Looper.java:226)
       at android.os.Looper.loop(Looper.java:313)
       at android.app.ActivityThread.main(ActivityThread.java:8757)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)


From the stack trace, we learn that this issue arises because line 205 of KlaviyoApiClient.kt is executed twice, indicating that handlerThread.start() is being called twice. This is the root cause of the IllegalThreadStateException being thrown.


From the code analysis, it's clear that Klaviyo.setPushToken() is being called in both the callback registered in the Application's onCreate() and in KlaviyoPushService's onNewToken(). If you check the thread id in the logs, you will find that Klaviyo.setPushToken() is running on the main thread within the Application's callback, while in KlaviyoPushService, it's executed on a worker thread. Since Klaviyo.setPushToken() lacks synchronization and is not thread-safe, in a multi-threaded scenario, it's possible for the handlerThread.start() to be executed twice due to a race condition. This leads to the occurrence of the error.

The Klaviyo Android SDK version information

1.3.1

Device Information

No specific

Android Studio Version

No specific

Android API Level

No specific

UninitializedPropertyAccessException on setPushToken

Description

When setting a push token the app might crash. It's a rare crash that I can't recreate, but it does happen for some people.

Checklist

  • I have determined whether this bug is also reproducible in a vanilla Android project
  • If possible, I've reproduced the issue using the main branch of this package.
  • This issue hasn't been addressed in an existing GitHub issue or pull request.

Expected behavior

Push token should be set (and it is most of the time!).

Actual behavior

Fatal Exception: kotlin.UninitializedPropertyAccessException: lateinit property initialBody has not been initialized
       at com.klaviyo.analytics.networking.requests.PushTokenApiRequest.equals(PushTokenApiRequest.kt:96)
       at java.util.concurrent.ConcurrentLinkedDeque.contains(ConcurrentLinkedDeque.java:1081)
       at com.klaviyo.analytics.networking.KlaviyoApiClient.enqueueRequest(KlaviyoApiClient.kt:118)
       at com.klaviyo.analytics.networking.KlaviyoApiClient.enqueuePushToken(KlaviyoApiClient.kt:81)
       at com.klaviyo.analytics.Klaviyo.setPushToken(Klaviyo.kt:153)


### Steps to reproduce

```markdown
Klaviyo.initialize(BuildConfig.KLAVIYO_API_KEY, application)
application.registerActivityLifecycleCallbacks(Klaviyo.lifecycleCallbacks)
FirebaseMessaging.getInstance().token.addOnSuccessListener { pushToken ->
    Klaviyo.setPushToken(pushToken)
}

The Klaviyo Android SDK version information

1.3.5

Device Information

Samsung Galaxy S21 FE 5G, Android 14 | Samsung Galaxy Note9, Android 10 | Samsung Galaxy S9+, Android 10 | Samsung Galaxy A42 5G, Android 12

Android Studio Version

2023.1.1

Android API Level

34

Manually logging OPENED_PUSH not showing on klaviyo's dashboard

Description

We are trying to integrate Klaviyo's notification into project that already uses Firebase Messaging.
In FirebaseMessagingService's onMessageReceived we customize how the notification looks, so we are not able to use KlaviyoNotification to display notification.

So we extract the information from Klaviyo's notification and display.

    val isKlaviyoNotification = remoteMessage.isKlaviyoNotification
    val title = if (isKlaviyoNotification) remoteMessage.title else remoteMessage.notification?.title
    val body = if (isKlaviyoNotification) remoteMessage.body else remoteMessage.notification?.body
    val deepLinkUri = if (isKlaviyoNotification) remoteMessage.deepLink else remoteMessage.data[DEEP_LINK_KEY]?.toUri()

// ... displaying notification with custom intent

Then when notification clicked, if it is Klaviyo's notification we are trying to track it like this:

            if (isKlaviyo) {
                storage.getPushNotificationsToken()?.let { token ->
                    klaviyoManager.logOpenedPush(token, id.orEmpty())
                }
            }

Tracking method:

    fun logOpenedPush(pushToken: String, notificationId: String) {
        val event = Event(EventType.OPENED_PUSH)
            .setProperty(EventKey.PUSH_TOKEN, pushToken)
        if (notificationId.isNotEmpty()) {
            event.setProperty(EventKey.EVENT_ID, notificationId)
        }
        klaviyo.createEvent(event)
    }

I couldn't find any document related to loggin EventType.OPENED_PUSH manually except in the code of EventKey:

/**
 * All event property keys recognised by the Klaviyo APIs
 * Custom properties can be defined using the [CUSTOM] inner class
 */
sealed class EventKey(name: String) : Keyword(name) {
    object EVENT_ID : EventKey("\$event_id")
    object VALUE : EventKey("\$value")

    /**
     * For [EventType.OPENED_PUSH] events, append the device token as an event property
     */
    object PUSH_TOKEN : EventKey("push_token")

    class CUSTOM(propertyName: String) : EventKey(propertyName)
}

So I added push_token as shown above in my tracking opened push

Checklist

  • I have determined whether this bug is also reproducible in a vanilla Android project
  • If possible, I've reproduced the issue using the main branch of this package.
  • This issue hasn't been addressed in an existing GitHub issue or pull request.

Expected behavior

I expected to see open rate on Klaviyo's dashboard in campaign report

Actual behavior

It shows only Delievered notifications number

unnamed

Steps to reproduce

Log OPENED_PUSH without using Klaviyo's handleNotification and newIntent

The Klaviyo Android SDK version information

1.1.0

Device Information

Emulator

Android Studio Version

Flamingo Patch 2 ( latest )

Android API Level

API Level 33

I am getting error when i try integrate klaviyo sdk with android app

Description

I am getting below error : 
> Task :app:processDebugResources FAILED

Execution failed for task ':app:processDebugResources'.
> A failure occurred while executing com.android.build.gradle.internal.res.LinkApplicationAndroidResourcesTask$TaskAction
   > AAPT2 aapt2-7.0.3-7396180-osx Daemon #0: Unexpected error during link, attempting to stop daemon.
     This should not happen under normal circumstances, please file an issue if it does.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

here is build.gradle  app level gradle dependencies 

dependencies {

    implementation "com.github.klaviyo.klaviyo-android-sdk:analytics:2.0.0"
    implementation "com.github.klaviyo.klaviyo-android-sdk:push-fcm:2.0.0"
}

build.gradle project level 

 dependencies {
        classpath 'com.android.tools.build:gradle:7.0.3'
        classpath 'com.google.gms:google-services:4.3.10'
        // Add the Crashlytics Gradle plugin
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
        classpath 'com.vanniktech:gradle-maven-publish-plugin:0.15.1'

    }

please help me how to fix this issue .

Checklist

  • I have determined whether this bug is also reproducible in a vanilla Android project
  • If possible, I've reproduced the issue using the main branch of this package.
  • This issue hasn't been addressed in an existing GitHub issue or pull request.

Expected behavior

Code should build successfully

Actual behavior

I am getting above error

Steps to reproduce

try to add gradle dependencies

The Klaviyo Android SDK version information

2.0.0

Device Information

compileSdkVersion 34 // Update to API level 34
ndkVersion '25.2.9519653'
buildToolsVersion "34.0.0" // Update to the corresponding build tools version

defaultConfig {
    applicationId "com.test.android"
    minSdkVersion 23
    targetSdkVersion 34
    versionCode 69
    versionName "3.20"
    multiDexEnabled true

}

Android Studio Version

Android Studio Hedgehog | 2023.1.1 Patch 1
Build #AI-231.9392.1.2311.11255304, built on December 27, 2023
Runtime version: 17.0.7+0-17.0.7b1000.6-10550314 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 14.2.1
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 8
Metal Rendering is ON
Registry:
external.system.auto.import.disabled=true
ide.text.editor.with.preview.show.floating.toolbar=false
ide.instant.shutdown=false

Non-Bundled Plugins:
Dart (231.9411)
PythonCore (231.9225.4)
io.flutter (77.1.2)

Android API Level

34

Test issue

Issue Overview

Just testing our zapier integration

Expected behavior

Actual behavior

Steps to reproduce

Add a .unregisterPushPayload() API method

Description

I'm looking for a way to unsubscribe (opting out) our users from a push subscription. Looking at the available SDKs, iOS has a way to unsubscribe the users:

https://github.com/klaviyo/klaviyo-swift-sdk/blob/bb2506d192a8cdb9396c81061a90469c1f2c1486/Sources/KlaviyoSwift/KlaviyoAPI.swift#L121

        case .unregisterPushToken:
            return "client/push-token-unregister"
        }

Proposed Solution

Klaviyo Android SDK should have an equivalent API or method caller for the API **Unregister Push Payload**:
https://developers.klaviyo.com/en/reference/unregister_client_push_token

Alternatives Considered

- Calling HTTP directly, but seems like a hacky solution, considering we're using an SDK for other APIs

Additional Context

- We're building on top of Flutter, so we're building a communication interface using [platform channels](https://docs.flutter.dev/platform-integration/platform-channels)

Notification not receiving when the app is killed. (lock screen)

Description

When the app is in the background or the foreground, notifications are received as expected. However, when the app is killed (e.g., removed from the recent apps list or on the lock screen), notifications do not appear.

Checklist

  • I have determined whether this bug is also reproducible in a vanilla Android project
  • If possible, I've reproduced the issue using the main branch of this package.
  • This issue hasn't been addressed in an existing GitHub issue or pull request.

Expected behavior

Notifications should be received even when the app is not actively running or is in the background.

Actual behavior

Notifications are not received when the app is in the killed state (lock screen).

Steps to reproduce

Ensure the Klaviyo-integrated app is installed.
Launch the app.
Receive a notification when the app is in the background or foreground (working as expected).
Kill the app (e.g., remove it from the recent apps list).
Send a notification to the device.

The Klaviyo Android SDK version information

1.3.4

Device Information

pixel 6

Android Studio Version

Android Studio Giraffe | 2022.3.1 Patch 2

Android API Level

33

Weird behaviour with external_id

Description

I noticed, that this SDK for some reasons also push external_id to custom properties.

So, I see it twice at profile page at dashboard.

Checklist

  • I have determined whether this bug is also reproducible in a vanilla Android project
  • If possible, I've reproduced the issue using the main branch of this package.
  • This issue hasn't been addressed in an existing GitHub issue or pull request.

Expected behavior

No response

Actual behavior

No response

Steps to reproduce

No response

The Klaviyo Android SDK version information

1.1.0

Device Information

No response

Android Studio Version

No response

Android API Level

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.