exponea / exponea-ios-sdk

MIT License
19 stars 27 forks source link

Unable to update apple_push_notification_id #60

Closed sebastianmraz closed 4 months ago

sebastianmraz commented 4 months ago

Tested on: xcode: Version 15.0 (15A240d) iPhone: 12 Pro(iOS 17.4) Exponea:

All things started when a BadDeviceToken error occurred while attempting to send a notification. After fixing the implementation of token refreshing at app start, strange occurrences began to happen. Currently, we register push tokens for users using the following code:

        let customerIds = ["registered" : customerID]
        let properties = [
            "apple_push_notification_id" : token
        ]

        Exponea.shared.anonymize()
        Exponea.shared.identifyCustomer(customerIds: customerIds, properties: properties, timestamp: nil)
        Exponea.shared.trackPushToken(token)

During debugging, I noticed that both Exponea.shared.identifyCustomer and Exponea.shared.trackPushToken end up in the same place in your library with a similar stack trace. It seems that both are attempting to achieve the same goal – adding the token for the customer in the Exponea app.

Upon further investigation, we discovered another issue, that seems that it could be connected with Exponea lib. Even after changing the implementation, we still encountered BadDeviceToken errors in some cases. This occurred because there was no change in the Exponea customer database after executing the provided code. Upon reviewing the code, it appears that data about the customer is correctly saved in your DatabaseManager class. However, the customer is only updated with the correct token after killing and restarting the application. The same issue applies to the anonymize function, which does not remove the token from the customer until the application is killed and restarted. Could this be connected with Exponea implementation or we should continue trying to find issue in our code. Could this issue be connected with the Exponea implementation, or should we continue trying to find the issue in our code?

Ankmara commented 4 months ago

Hi, could you show me your decoding of deviceToken (Data -> String)? Thank you

sebastianmraz commented 4 months ago

It should look something like this

 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

        NotificationManager.shared.setupUserToken(with: tokenString)
    }

it is calling this function

func setupUserToken(with token: String) {
        UserDefaultsService.exponeaNotificationToken = token
        self.configureExponeaPush()
    }

and that ends up here in this function

private func configureExponeaPush() {
        FireBaseEventManager.tryExponeaPushNotificationRefresh()
        guard let userID = LocksmithService.getCurrentSession()?.drsId, let token = UserDefaultsService.exponeaNotificationToken else { return }

        let customerID = exponeaCustomer(dsrID: userID)

        Log.i("Device Token: \(token)")
        Log.i("DSRID:  \(customerID)")

        let customerIds = ["registered" : customerID]
        let properties = [
            "apple_push_notification_id" : token
        ]

        Exponea.shared.anonymize()
        Exponea.shared.identifyCustomer(customerIds: customerIds, properties: properties, timestamp: nil)
        Exponea.shared.trackPushToken(token)
        FireBaseEventManager.exponeaPushNotification(user: customerID, token: token)
    }

Code snipped i have provided in issue is from configureExponeaPush function.

Ankmara commented 4 months ago

Hi, thank you for code. Yes, it could be issues on our side. Did you try to use "handlePushNotificationToken" instead of "setupUserToken" insinde "didRegisterForRemoteNotificationsWithDeviceToken"

sebastianmraz commented 4 months ago

Hello, yes we tried both handlePushNotificationToken(deviceToken: Data) and handlePushNotificationToken(token: String) on multiple places. First i tried using it directly in appdelegate function and than in our setup user function. It did not change anything about app functionality. We still need to kill the application and open it again for token to be updated in exponea customer database

Ankmara commented 4 months ago

Hi, thank you for response. Which case of flushMode do you have please?

sebastianmraz commented 4 months ago

Historically it was implemented like this Exponea.shared.flushingMode = .automatic and it remains the same until this day, but can this by itself impact the process of uploading data to Exponea? I understand this as just a flushing logic of the data that was already uploaded(and it was not until we killed the application and ran it again)

Ankmara commented 4 months ago

Can you try to use .immediate for flushMode please?

sebastianmraz commented 4 months ago

It seems that .immediate is working and it does fix my issue with uploading, but with using the .immediate option I am worrying about app performance(a lot of things are being tracked with Exponea). Now the question is, why .automatic option does not work when the application enters the backgroud and only works when killing the application.

Ankmara commented 4 months ago

Thank you for response. Performance should be good and we will check .automatic. Thank you