Push token changed after which event

Hi all,

does anybody know after which event the push token of a device is changed?
After a store app update?


I’m curious too. When I delete and reinstall the Expo client I noticed my pushtoken changed, the old pushtoken seems to stay connected to my device since some of the users receive a single notification more than one time.

I also found Notifications.getDevicePushTokenAsync(); is available for standalone apps, does this token behave like a regular APNS/GCM token?

@ide can you explain in some more detail how this all works?

With a Expo, the Expo push token never changes for as long as an app is installed. If the user uninstalls and reinstalls an app they will get a new Expo push token. On Android, if they clear the app’s data they will get a new Expo push token.

The Expo client sends the Expo push token and the native device token to the Expo servers. The native device token can change at any time the app is launched; different versions of iOS have different behavior for when to refresh the device token. Apple does not document the specific behavior and I don’t think Google does either.

On iOS (this may have changed in 11 though — it’s not documented) it is possible for one app to have two valid device tokens according to some Stack Overflow posts. This means in a traditional iOS app, the user could receive double notifications. Usually the layer of indirection from the Expo push token prevents this but not in the case when a user gets a new Expo push token (described above).

Thanks for your detailed and helpful answer! I guess there is no fool proof solution to make sure a device registers only once then… :thinking:

@ide Hi, in my production environment I notice that most users have more than one token ( some have 50 ), also I have the case when users don’t receive any notifications although notification API return status ok for all his push tokens, I notice that happen when user have many push token (more 10), can you recommend me what should I do in this situation? Maybe i should bind token not only for the user and for user/deviceID, could this help me?

A user should not have more than one Expo push token unless they clear their app data or uninstall and re-install the app. The Expo push token is otherwise consistent.

For notifications that return “ok” – you must check both the result of the send endpoint and the getReceipts endpoint. “ok” in the push ticket from sending means that Expo received the notification, while “ok” in the asynchronous push receipt means that Apple/Google received the notification.


  1. On every app launch, I run Notifications.getExpoPushTokenAsync and send to the backend token, backend store token by unique userId/token
  2. Yes, I check, I am using expo-server-sdk-node (3.0.1), sometimes I get DeviceNotRegistered and delete this user/token, but anyway, some users still have more than one token and all them got status ok from getReceipts endpoint

Also, i notice users that have more one token have the devices iPhone 5,6

  1. If you are seeing different Expo push tokens, the most likely explanation is that the user re-installed the app, logged in with another device, or cleared their app data through some other means.
  2. If the getReceipts endpoint is returning “ok”, that means Apple/Google received the notification successfully. It doesn’t necessarily mean the device received the notification (e.g., the user may have uninstalled the app or revoked the remote-notification permissions). If your notification payload is correctly formatted, I don’t think there is anything more you can do in this scenario; Apple acknowledged successful receipt of the notification so your push credentials were correct and the push notification payload was not too large.

Probably this answer doesn’t exist…but if we want to support users logging on multiple phones and send push notifications to those phones.

Since we don’t have a unique identifier for the phone…it’s possible that we register multiple expo push tokens on the same phone for the same account.

What is the best way to handle one login on multiple phones but know to overwrite the push token per-device?

Expo push tokens are designed to be stable for a given installation of an app or longer.

This means that if you install an app and get a push token, you will also get the same push token a month from now as long as the app remained installed. If the app is uninstalled and reinstalled, the Expo push token may or may not change — the API contract is that the push token is stable for at least as long as the app is installed.

If a phone is restored from backup, the Expo push token will change as of the latest version of expo-notifications (winter 2020). This way, when you buy a new phone and set it up from a backup of your old one, your new phone will get a different, separate Expo push token than your old phone’s.

If an app is uninstalled (or if notification permissions are revoked and other conditions that would stop notifications), after awhile the token will no longer be able to send messages until the app re-registers for push notifications. Google and Apple control when they decide to mark a token as unregistered —it’s not as simple as uninstalling an app and sending it a notification. Your server must asynchronously check the push receipts to learn when a token is unregistered and to stop sending notifications with it. This lets you handle the case when someone stops using a device or has uninstalled the app.

Mapping push tokens to user accounts is entirely up to the application code. If someone logs into multiple devices, it’s up to you how you want to handle that. You’d probably write your server almost the same way as if you were writing an Android or iOS app without Expo.

1 Like

Perfect answer! Thanks!

@ide I’m trying to find an example response for [ addPushTokenListener(listener: PushTokenListener): Subscription ] but i cant find it anywhere, could you help me with this?

(Notifications - Expo Documentation)

Thanks in advance!

Hey @aryk I just needed some way to contact you. Did you ever find a workaround or solution to the camera tilt bug? I’m running into the issue myself right now. I’m referencing your original post, which never got answered, and is locked. Orientation Bug with <Camera> Component?