[Push Notifications] Old and new Notifications API return different push notification tokens for the same device

Please provide the following:

  1. SDK Version: 38
  2. Platforms(Android/iOS/web/all): all

Hi, I’m upgrading from Expo SDK 37 to Expo SDK 38.
I’m using the Expo push notification services in my app, and my server stores the Expo Push Notification Tokens in a db.

I just realized that, after upgrading to Expo SDK 38 (by following the guide) and doing some testing, the old Notifications API (still supported) returns a different ExpoPushNotificationsToken than the newest one.

In our system, this means that users will have to set up push notifications again in their phones, whenever they upgrade to the latest app version, which is something it shouldn’t happen, ideally. This is because we allow users to have push notifications enabled for many devices, for the same account.

I also see the new getExpoPushTokenAsync accepts some (optional) parameters, so I wonder if can make the new Notifications API to return exactly the same PushNotificationToken than the old Notifications API by passing a combination of these parameters.

Am I missing something here?
Thank you!

Hello, @manumid

The ExpoToken is like an user identifier that contains info about Android/iOS/Web APN’s user token to send push messages. I think that it has to be different identifiers for to different methods for sending notifications true from Expo Servers to Google Servers.

Hi Victor, thanks for the quick response!

So, if the ExpoToken contains device information to receive push notifications, shouldn’t that be the prove that both APIs have to return the same token?

I mean, from a user perspective, I’d have expected both the old API and the new API to have exactly the same use case, and thus exactly the same output, no matter which one I’m using. In my head (also as stated here), the expo token is a unique device identifier (for push notifications) in which lifetime is the app installation itself. That is, the expo token would be renewed if we uninstall the app and re-install it again, but it should be the same when upgrading it - the latter is the most common case when upgrading the Expo SDK version, which requires a new APK submission to the AppStore/PlayStore, and thus it requires users to “upgrade” their app.
In this case, this invariant would break, and thus it would enforce us to tell our users “hey, you have to set up push notifications again in order to make them work correctly”, which is not a great experience for them.

Also it’s worth to mention that both tokens work at the same time. That is, I can send push notifications to the phone, by using any of them. But since the old API will be deprecated soon (perhaps in SDK 39?) then I have to find a way of using the new API, without letting the end user know about it).

Does this make sense?
Thank you again!

Another thing worth to mention (that I’ve just realized about), is that:

  • For Android, both APIs return a different token in both development (Expo client) and production (standalone app)
  • For iOS, both APIs return a different token in development (Expo client), but in production (standalone app) they return exactly the same token.

This got me a bit more confused I think, since now it seems this behaves a bit differently regarding the OS, and also regarding if whether we’re in development or in a standalone app.

Hey @manumid , you got it wrong, ExpoToken is unique, but not a device identifier.
Are you familiar with how push notifications work?

This is How to send, but…


See More Here

To Store your device token

Firebase Cloud Messaging “Google Token”, is not the “Expo Token”,
On your device it should be something like:

If iOs:

  • Nativilly get Apple APN’s token - ‘xxxxsomeAppleTokenxxxx’
  • Send this token to Expo’s Server
  • Expo’s Server store verify if the ‘xxxxsomeAppleTokenxxxx’ is stored
  • If yes:
    • return existent ExpoToken for Apple APN’s token ‘xxxxsomeAppleTokenxxxx’, ‘ExpoPushToken[xxxxxx]’
  • If Not:
    • Expo’s Server will create a new ExpoPushToken, save Apple APN’s info on server
    • return created ‘ExpoPushToken[xxxxxx]’ for ‘xxxxsomeAppleTokenxxxx’

If Android:

  • Natively get Apple Firebase Cloud Message token - ‘xxxxsomeFCMtokenxxxx’
  • HERE, the device returns a different value for OldNotificationAPI of Android (not expo) or New Notification API. This is a difference of native Android OS, not expo’s.
  • Send this token to Expo’s Server
  • Expo’s Server store verify if the ‘xxxxsomeFCMtokenxxxx’ is stored
  • If yes:
    • return existent ExpoToken for Apple APN’s token ‘xxxxsomeFCMtokenxxxx’, ‘ExpoPushToken[xxxxxx]’
  • If Not:
    • Expo’s Server will create a new ExpoPushToken, save Apple APN’s info on server
    • return created ‘ExpoPushToken[xxxxxx]’ for ‘xxxxsomeFCMtokenxxxx’

@manumid Let me know if it came more clear, sorry if don’t.

Thank you Victor for being so clear in your response.
Yeah, I think I was kind of familiar regarding how the Expo push notification service delivery works (i.e. based on the expo token, the Expo servers “forward” the push notification to either FCM or APN), but didn’t know about the difference in Android for the old and new notifications API.

Still, I don’t understand why that happens. You mentioned that this is due to some Android’s OS internals. Do you know if there’s a specific reason under the hood?

And after thinking about that for a bit, it seems there’ are no chances I could make the new API to return exactly the same token as before, right? This tells me that, besides storing the instead of saving the Expo token only, I should also store the device token in order to deduce if whether the expo token belongs to a given device or not, right?

Thank you again! :+1:

@manumid it depends on “why you need that token be equal”, there’s more info:

Another way to change the ExpoToken is if the user uninstall the app and install again, for security reasons when the user Remove your app de Native Push Token is invalidated end when the app is reinstalled a new Native Push Token is generated. Each App and Each Installation has your on Native token.

No, i don’t know exactly why Native Old and New Apis gives different tokes,but probably it has some unknown motive.

If you need a Hash to identify the User Unic device you will find a lot of people facing this issue, a lot of developers try to get device MEI, ou Wifi MAC address but apple and android OS updates make this more difficult for developers to let the user private info more secure and untraceable.

But tell me more about your real problem.
=D

Right, that makes a lot of sense.

Yeah, the main problem in our side is that, in our system, we allow each user to have more than one “push notification” config. That is, each user can have push notifications enabled for more than one device.

Thus, the only “device information” we have in the backend is just the expo push notification token. That is, we use that so to deduce if your app has push notifications configured or not. Also consider that we’ll send push notifications only if the user wants (i.e. this is part of the push notification config).

Since now the new API returns a different token, then we’d lose the already existing push notification config for Android devices, and thus users would have to “re-configure” this, and that isn’t ideal since our users don’t (and don’t have to) know how push notifications work under the hood.

This tells me that we may want to use the native tokens, since they work better as “device push config identifier” let’s say. Otherwise I may need to start thinking on a migration mechanism that’s capable of saving the token given by the new API, by fetching the current config (using the old API).

Does this make sense?
Thanks again for the help :+1:

1 Like