How does a push token get "reregistered"?

Apple documentation states that it is possible for a push token to be "reregistered". What is the scenario in which that can happen? Why would feedback service think something was uninstalled but then that push token is made valid again?


https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/BinaryProviderAPI.html#//apple_ref/doc/uid/TP40008194-CH13-SW12

Accepted Reply

Yeah, that is what I'm saying. Tokens end up in the feedback service list because device was contacted and the push notification was rejected.


One of the reasons for that to happen is the app being uninstalled. But the same thing should happen if the device is updated. And you should test to see what happens in the following sequence:


1. User launches the app and the app registers for push notifications.

2. User goes in to settings and disables push notifications for the app.

3. You try to send a push using that token.


That should also end up with that token getting reported by the feedback service. And if the user turns push notifications back on, the app may see the same token as before or it might get a different one.

Replies

By "reregistered" the documentation means that it's possible for the device token to be reused. So it's possible to see the following sequence:


1. Device registers for push using token X

2. App uninstalled, invalidating token X.

3. Push send using token X.

4. Device registers for push using token X.

5. Your server checks the feedback service and sees token X reported invalid at timestamp before X was registered for the second time.

Ok that makes sense. Is it possible for Apple feedback to send an "uninstall" token for an app that in fact has not been uninstall? I am persisting some data in the apps sandbox Library folder (not cache) that exists during the lifetime of that App install. If the app is uninstalled, my assumption is that the file is removed. If the app has been re-installed, I will get a new file. However, I am seeing an uninstall event from APNs feedback, but no recreation of this persistent file. That either makes me believe that there is another scenario in which apple thinks an app is uninstalled but it actually is not, OR, sandbox data isnt fully deleted during an uninstall and if the app is reinstalled quickly that data can bleed across installs.


Have any experience with either of those potential scenarios?

Here's one of the cases that the documentation calls out:


To protect user privacy, do not use device tokens to identify user devices. Device tokens change when the user updates the operating system and when a device’s data and settings are erased. As a result, apps should always request the current device token at launch time. For more information, see 'Device Token Generation and Dispersal'.


It seems to me that, if you're looking at the documentation for the feedback service, that business about "A timestamp (as a four-byte

time_t
value) indicating when APNs determined that the app no longer exists on the device" is probably misleading or wrong. If APN contacts the device and the push token is no longer valid (for whatever reason, whether the user uninstalled the app, updated iOS, or just turned notifications off) that should all get lumped in to "Device contacted successfully, but token rejected" and get listed in the feedback service.


So, whether it's due to one of the reasons mentioned or due to some bug in iOS, tokens sometimes change for what are going to feel like no good reason. It's well reported to be true for things like the advertising identifiers, I wouldn't be at all surprised that the same is true for push tokens.

Yea we arent trying to track via the push token itself. we do request a new token each time the app is launched. maybe the assumption that tokens given to us via the APNs feedback service are ONLY uninstalls is an incorrect assumption. Just so I understand what you are suggesting, an uninstall is not the only cause for a push token to be given to me via the APNs feedback service? I had a theory that it may have had something to do with an iOS update but wasnt sure. iOS update COULD invalidate the tokens but would not indicate an uninstall

Yeah, that is what I'm saying. Tokens end up in the feedback service list because device was contacted and the push notification was rejected.


One of the reasons for that to happen is the app being uninstalled. But the same thing should happen if the device is updated. And you should test to see what happens in the following sequence:


1. User launches the app and the app registers for push notifications.

2. User goes in to settings and disables push notifications for the app.

3. You try to send a push using that token.


That should also end up with that token getting reported by the feedback service. And if the user turns push notifications back on, the app may see the same token as before or it might get a different one.

One more question for you since you seem to be well versed in the feedback service. If a debug push cert is used to try to push to a signed production app (or vice versa) will that failed push show up in the feedback service? or just go missing?

I think you're asking a trick question due to a few mitigating factors:

  • The production and debug push servers probably won't recognize the other certificate as valid.
  • The debug and release versions of the app are probably going to have different push tokens.
  • It's possible that there's token collision between the debug and production servers. In other words, the same token might reference device A for the production server and device B for the debug server.


So if you send a push to the wrong server, you're probably going to see a mix of all three results, depending on the current implementations:

  • Successful sends
  • Push sits in queue forever undelivered
  • Devict contacted but push rejected due to token change

Because the rules concerning which of the servers get contacted is undocumented (and thus subject to change) if I'm remembering right.


In other words, it's the perfect situation for a "It worked when I tried it" bug in your code.