Skip to content
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

3rd party SDKs not able to receive a device token with autoFetchDeviceToken enabled #131

Open
Samox opened this issue Mar 18, 2024 · 27 comments
Assignees
Labels
bug Something isn't working iOS SDK

Comments

@Samox
Copy link

Samox commented Mar 18, 2024

Issue causing 3rd party SDKs, like Expo notifications, not receiving device tokens when registered to the device, contrary to expected behavior.

Expected Outcome

  • Add 3rd party SDK to your app (such as Expo notifications).
  • Enable autoFetchDeviceToken.
  • Ensure that when a device token is registered to the device, both the 3rd party SDK and the CIO SDK receive this device token.

Current Outcome

  • When a device token is registered, only the CIO SDK receives the device token; the 3rd party SDKs do not receive a callback with the device token.

Impact on Customers

  • Customers who use 3rd party SDKs to receive push notifications might be impacted.
    • Here is a customer who is using the Expo push service that is not able to receive a token.

Debugging

In UIKit sample app, I added this code block to the AppDelegate.swift file:

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let foo = "" // set breakpoint here
    }

When setting a breakpoint in that function, the breakpoint does not get triggered. I expected to see this behavior because looking at the swizzling code when a device token is registered to the CIO SDK, the function that gets called by swizzling does not call the original implementation that swizzling replaced.

I believe this is the issue. If the AppDelegate breakpoint does not get triggered, 3rd party SDKs are also not getting called with the device token.

I found a Swift swizzling implementation from another open source SDK on github. Could be a good resource for us to find a working Swizzling implementation for register device tokens.

References

@levibostian
Copy link
Contributor

Sorry to hear you're having issues, Samox. Let me see if we can help.

Here are some questions and comments that I have to help debug this.

@linear linear bot closed this as not planned Won't fix, can't repro, duplicate, stale Mar 18, 2024
@levibostian
Copy link
Contributor

Oh, sorry for the issue being auto-closed. I'm new to using Linear.

@levibostian levibostian reopened this Mar 18, 2024
@Samox
Copy link
Author

Samox commented Mar 19, 2024

Hello thanks for your quick response!
My answers for your questions:

  • Yes the notifications are enabled
    CleanShot 2024-03-19 at 10 10 10@2x

  • The flow is we first login the user, then prompt to accept the notifications. After login this code runs.

 if (Device.isDevice) {
    const { status: existingStatus } = await Notifications.getPermissionsAsync();
    let finalStatus = existingStatus;
    if (existingStatus !== 'granted') {
      const { status } = await Notifications.requestPermissionsAsync();
      finalStatus = status;
    }
    if (finalStatus !== 'granted') {
      console.warn('Failed to get push token for push notification!',  finalStatus);
    }
    console.log('This works', finalStatus);

    const expoPushToken = await Notifications.getExpoPushTokenAsync({
      projectId: Constants.expoConfig.extra.eas.projectId,
    }); -> We are stuck here. Promise is not resolved, and does not throw either
    

    console.log(`Push token: ${expoPushToken.data}`);

Some more info:

  • My iPhone is on 17.3.1
  • The bug happens on a build with the customerio-expo-plugin. We also use intercom to send notification. I tried a build without the intercom plugin, still have the issue.
  • I tried with and without the SDK initiation https://customer.io/docs/sdk/expo/getting-started/#initialize-the-sdk No impact on the bug.
  • I tried with disableNotificationRegistration true and false, No impact on the bug.

@levibostian
Copy link
Contributor

Thank you for all of that info. Very helpful!

For the next step of debugging, we would like to review these files from your ios/ directory of your app:

  • AppDelegate.mm
  • AppDelegate.h
  • Podfile
  • Podfile.lock

It's understandable that some of these files have sensitive information inside of it. Feel free to send those files to win@customer.io and in the email, link to this github issue. The team will route the message appropriately when they receive it.

@Samox
Copy link
Author

Samox commented Mar 19, 2024

Info sent by email :)

@simontoulouze
Copy link

+1, same problem with Expo SDK 49, I am not able to access notification content when it is received or tapped and neither to access the push token (even if it seems to be successfully sent to Customer.IO, I cannot manage logging it)

@levibostian
Copy link
Contributor

Thank you for sending that information, Samox. I can confirm that I have received the files.

Our team will dig into this deeper, trying to reproduce the issue. We'll come back if we have more questions or comments.

@levibostian
Copy link
Contributor

@simontoulouze, sorry to hear that you have been experiencing an issue.

If you don't mind, could you open a new issue and describe the behavior the you're experiencing? The expected behavior you expect to see as well as actual behavior you're getting?

Code snippets showcasing what you're trying to accomplish is also very helpful. We would be happy to review this for you.

@levibostian
Copy link
Contributor

Samox, have you used customer.io in your app before or is this a new install?

If you have used customer.io before, what version of the Expo plugin have you tried? What versions gave you a token successfully and what versions did not give you a token?

I am not sure if you're using a bare or managed workflow. If you're able to, could you try to modify your file ios/PushService.swift with this change and then run your app again?

    // In this file, leave everything else the same. Only modify this 1 line. 
    MessagingPushAPN.initialize { config in
      // Add this line of code: 
      config.autoFetchDeviceToken = false 
    }
  }

Thank you for working with me to debug this. We are continuing to try and reproduce this from our end. Any answers you can provide here will help expedite being able to figure out the issue.

@Samox
Copy link
Author

Samox commented Mar 20, 2024

Yeah I did not want to make it more complex, but the first time I installed the plugin (2 weeks ago) it worked perfectly, then last week it did not. I don't now what changed. I tried to reproduce the case when it worked, but I was unable to, and became crazy.
I don't know if it is a version of one the packages, or my local version of expo/eas that changed.

We have a managed installation with expo.
I think I have used only the 1.0.0-beta.15 of customerio-expo-plugin

I'll try a build with the line autoFetchDeviceToken = false

@Samox
Copy link
Author

Samox commented Mar 20, 2024

🎉🎉🎉🎉
It works with the config.autoFetchDeviceToken = false!

It changes my workflow though since I need to prebuild the ios folder, do you think you can release a fix soon ?
I'll try to make it work with a local patch in the meantime.

What is the impact of autoFetchDeviceToken is it something I should keep in mind ? Can I deploy my build in production with it ?

@Samox
Copy link
Author

Samox commented Mar 20, 2024

I opened this PR #132 to properly configure the plugin

@levibostian
Copy link
Contributor

Glad to hear that the autoFetchDeviceToken option helped you!

What is the impact of autoFetchDeviceToken is it something I should keep in mind ? Can I deploy my build in production with it ?

autoFetchDeviceToken is a completely valid config option and one that you can feel safe enabling in a production app. Before you push to production, I would test to make sure that you're able to see devices get added to profiles in Customer.io. Create a new profile in Customer.io in your app and confirm that a device gets added to it.

The reason that this config option is not exposed as an Expo plugin config option is that you should not need to modify this config option. If you feel the need to change this option, it is probably because there is a problem with the SDK or your app's setup of the Customer.io SDK.

I suggest continuing to use the patch that you have developed. We'll look into this deeper and provide a fix to fix this without a patch needed.

Thanks again for working with me to debug this issue!

@linear linear bot added iOS SDK bug Something isn't working Expo Plugin and removed Expo Plugin labels Mar 20, 2024
@linear linear bot changed the title Can't get IOS notifications push token 3rd party SDKs not able to receive a device token with autoFetchDeviceToken enabled Mar 20, 2024
@LeonRueda
Copy link

Hi! thanks for this info, I have been a bit blocked since we updated to the beta 15 because of this... I'm having the same issue with expo notifications and I have been trying these two to get along for quite some months already. It is not clear to me where to add @Samox's workaround, is it in the plugins on app.config? inside ios or inside pushNotification? Perhaps in the env object? I'm using the managed flow on expo... Thanks in advance!

@linear linear bot added Expo Plugin and removed Expo Plugin labels Apr 3, 2024
@levibostian
Copy link
Contributor

Sorry to hear you're experiencing this issue, @LeonRueda. Great question. Let me try and help.

You're looking for the file specified in this comment. So, a Swift file that's located in your ios/ directory. If you run expo prebuild --clean on your project and then search for the phrase "MessagingPushAPN.initialize" in the generated ios/ directory, you will find the file we are talking about.

I understand that this is not ideal. Continue asking questions if you have them!

@Samox
Copy link
Author

Samox commented Apr 4, 2024

My workaround was

  • install "patch-package"
  • add this patch in patches/customerio-expo-plugin+1.0.0-beta.15.patch
diff --git a/node_modules/customerio-expo-plugin/lib/commonjs/helpers/native-files/ios/PushService.swift b/node_modules/customerio-expo-plugin/lib/commonjs/helpers/native-files/ios/PushService.swift
index 0a0db95..2251e68 100644
--- a/node_modules/customerio-expo-plugin/lib/commonjs/helpers/native-files/ios/PushService.swift
+++ b/node_modules/customerio-expo-plugin/lib/commonjs/helpers/native-files/ios/PushService.swift
@@ -21,6 +21,8 @@ public class CIOAppPushNotificationsHandler : NSObject {
       config.autoTrackPushEvents = {{AUTO_TRACK_PUSH_EVENTS}}
     }
     MessagingPushAPN.initialize { config in
+      // Added line to fix issue https://github.com/customerio/customerio-expo-plugin/issues/131
+      config.autoFetchDeviceToken = false 
       config.showPushAppInForeground = {{SHOW_PUSH_APP_IN_FOREGROUND}}
     }
   }
diff --git a/node_modules/customerio-expo-plugin/lib/module/helpers/native-files/ios/PushService.swift b/node_modules/customerio-expo-plugin/lib/module/helpers/native-files/ios/PushService.swift
index 0a0db95..2251e68 100644
--- a/node_modules/customerio-expo-plugin/lib/module/helpers/native-files/ios/PushService.swift
+++ b/node_modules/customerio-expo-plugin/lib/module/helpers/native-files/ios/PushService.swift
@@ -21,6 +21,8 @@ public class CIOAppPushNotificationsHandler : NSObject {
       config.autoTrackPushEvents = {{AUTO_TRACK_PUSH_EVENTS}}
     }
     MessagingPushAPN.initialize { config in
+      // Added line to fix issue https://github.com/customerio/customerio-expo-plugin/issues/131
+      config.autoFetchDeviceToken = false 
       config.showPushAppInForeground = {{SHOW_PUSH_APP_IN_FOREGROUND}}
     }
   }
diff --git a/node_modules/customerio-expo-plugin/src/helpers/native-files/ios/PushService.swift b/node_modules/customerio-expo-plugin/src/helpers/native-files/ios/PushService.swift
index 0a0db95..2251e68 100644
--- a/node_modules/customerio-expo-plugin/src/helpers/native-files/ios/PushService.swift
+++ b/node_modules/customerio-expo-plugin/src/helpers/native-files/ios/PushService.swift
@@ -21,6 +21,8 @@ public class CIOAppPushNotificationsHandler : NSObject {
       config.autoTrackPushEvents = {{AUTO_TRACK_PUSH_EVENTS}}
     }
     MessagingPushAPN.initialize { config in
+      // Added line to fix issue https://github.com/customerio/customerio-expo-plugin/issues/131
+      config.autoFetchDeviceToken = false 
       config.showPushAppInForeground = {{SHOW_PUSH_APP_IN_FOREGROUND}}
     }
   }

`
``

@jordiup
Copy link

jordiup commented Apr 9, 2024

I've spent 12hrs troubleshooting this error 🤕 . I'm thinking I'll resolve to remove customerio entirely. Patching with config.autoFetchDeviceToken hasn't seemed to work.

Would be great to see this resolved

@levibostian
Copy link
Contributor

Sorry to hear you have encountered this issue, @jordiup.

Because you mentioned that setting config.autoFetchDeviceToken = false is not working for you, I would like to review some of the native iOS files in your app. Could you send these files from your ios/ directory of your app:

  • AppDelegate.mm
  • AppDelegate.h
  • Podfile
  • Podfile.lock
  • PushService.swift
  • Lastly, could you also send a code snippet in your app where you're calling await Notifications.getExpoPushTokenAsync. You can send the whole file where this code exists if that's easier for you.

It's understandable that some of these files have sensitive information inside of it. Feel free to send those files to win@customer.io and in the email, link to this github issue. The team will route the message appropriately when they receive it.

@louiepopp
Copy link

Experiencing the same issue. This issue was incredibly hard to debug and I imagine most people on Expo 48+ will experience it. @levibostian have you still not been able to reproduce it?

We are running a managed workflow with Expo 50. The issue arose after migrating up from Expo 48, where it worked fine with the Customer.io plugin.

When removing the Customer.io plugin from our build, we are able to get the device token just fine from Expo Notifications, using the recommended setup from Expo documentation. Patching the package with config.autoFetchDeviceToken = false hasn't worked for us either.

I believe the easiest way to replicate the issue is to simply spin up a managed Expo 50 app, integrate Expo Notifications and the latest version of this package, and trying to run Notifications.getDevicePushTokenAsync().

The solution I found for our case was using CustomerIO.pushMessaging().getRegisteredDeviceToken() to get the device token and passing it into the parameters of Notifications.getExpoPushTokenAsync({ devicePushToken }) which worked.
@jordiup This could potentially help unstuck you.

@levibostian
Copy link
Contributor

Thank you very much for this additional detail, Louie. We greatly appreciate it.

The solution that you mention is a good idea. Thanks for mentioning that for others.

Patching the package with config.autoFetchDeviceToken = false hasn't worked for us either.

I am very curious why this config change didn't help you. Do you have a sample app available that reproduces this? I am very interested in hearing more about this.

Thank you for debugging this issue with us, everyone. I agree, this issue has been hard to debug and so any additional code or details is appreciated.

@casanea
Copy link

casanea commented May 22, 2024

Hi,

Same issue here. Spent tons of hours trying to find the problem...

config.autoFetchDeviceToken = false solved the issue.

Please let us know once a new version with a fix is released!

@levibostian
Copy link
Contributor

Thank you for sharing setting the config to false solved the problem for you. We appreciate the time you've spent trying to resolve the issue. Sorry that this issue has caused frustration for yourself and others.

Rest assured, our team is actively working to resolve this issue and we will notify you once a new version with a fix is released.

@zdnk
Copy link

zdnk commented Jul 8, 2024

They have been promising a fix for this for ages. Yet nothing changes.

@tomrom-pomelo
Copy link

+1 to #131 (comment)

I request push tokens to sync to other 3rd party providers, and for new push tokens (i.e. the app just opened), getDevicePushTokenAsync and getExpoPushTokenAsync hang forever. Once I added config.autoFetchDeviceToken = false, it works again

@lethib
Copy link

lethib commented Jul 11, 2024

also +1 to #131 (comment) 🎉

I am using a managed workflow and I patch (using patch-package) it like this 👇

  • Navigate to node_modules/customerio-expo-plugin/src/helpers/native-files/ios/PushService.swift
  • Find the block that have the following code:
MessagingPushAPN.initialize { config in
      config.showPushAppInForeground = {{SHOW_PUSH_APP_IN_FOREGROUND}}
    }
  • Add the line config.autoFetchDeviceToken = false like this:
MessagingPushAPN.initialize { config in
      config.autoFetchDeviceToken = false
      config.showPushAppInForeground = {{SHOW_PUSH_APP_IN_FOREGROUND}}
    }
  • Run the patch-package command: npx patch-package customerio-expo-plugin

A customerio-expo-plugin patch file has normally been created !

@vandemberg
Copy link

Hi, I am running a managed workflow with Expo 50 too and I've had the same problem recently. But with the line config.autoFetchDeviceToken = false works ok. But I can include this solution to my project, because it's easy lost this knowledge and I make my build using the eas build cloud, So the IOS folder is builded from zero again.

Someone with a problem like this founded some solution?

@fobos531
Copy link

Hello @ami-aman @levibostian - is there a timeline for improving the experience for users affected by this issue? Either by exposing the autoFetchDeviceToken as a config plugin option or determining a different solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working iOS SDK
Projects
None yet
Development

No branches or pull requests