9

I had an issue where a user started receiving double notifications after uninstalling and reinstalling my app, as the device sent to my server 2 different APNS tokens - one from the first installation and the other after reinstalling the app. Since the tokens were different I could not know this is the same device.

Until iOS 9 came out, every time I uninstalled and reinstalled the app, I always got the same APNS, so it was easy to know that this is the same device the user used as before. Since iOS 9, it seems that the APNS token is changed on every installation.

My question is how to tell if a client uninstall and reinstall the app, and update his APNS token instead of adding a new token?

I am asking as this sounds to me like something most iOS developers had to handle, but I couldn't find any best practice from Apple on how to tackle this, so I hoped that other can share their experience with this issue.

Kuf
  • 17,318
  • 6
  • 67
  • 91
  • Do the user need to log in or identify himself to use the app and get notifications? – Ares Dec 15 '15 at 03:40
  • @ares Yes, but each user can have multiple devices connected, so when a user connects I can't tell if it a new device or APNS change after reinstall. – Kuf Dec 15 '15 at 03:45
  • How about attaching '[[UIDevice currentDevice] name];' to the token meta data? – Ares Dec 15 '15 at 04:12
  • @Ares the device name is not unique (e.g. 'Joe's iPhone') – Kuf Dec 15 '15 at 04:20
  • Why do you say you can't? This API is available from 6.0 `NS_AVAILABLE_IOS(6_0);`. I don't understand – sahara108 Dec 15 '15 at 04:27
  • 1
    @sahara108 I left work, I'll try tomorrow and report back, tnx – Kuf Dec 15 '15 at 04:28
  • @sahara108 the value might change after reinstalling the app, from [apple docs](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/#//apple_ref/occ/instp/UIDevice/identifierForVendor): `The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them` – Kuf Dec 15 '15 at 14:31
  • I though they changed it :(. So you'll need to write that value into your keychain. – sahara108 Dec 15 '15 at 14:37
  • @sahara108 thanks for the input – Kuf Dec 15 '15 at 15:34

1 Answers1

6

This is how we ended up solving it:

On each app launch:

  1. create push notification token
  2. is there a token in localstorage?
    • yes - compare the tokens to localstorage. are they identical?
      • yes - return
      • no - update server with new token, and after server response with 'OK' save it locally in local storage and keychain
    • no - check is there a token in keychain
      • yes - compare the tokens to keychain. are they identical?
        • yes - save token in localstorage and return
        • no - update server with new token, and after server response with 'OK' save it locally in local
          storage and keychain
    • no - update server with new token, and after server response with 'OK' save it locally in local storage and keychain

If anyone has a more elegant way to solve it I would love to hear about it

Kuf
  • 17,318
  • 6
  • 67
  • 91
  • I 'd prefer to use `identifierForVendor` key. On each app launch, check if value of `appnameVendor` key exits. If not load it from system and write down. Post to server the new token and that `appnamVendor`'s value. The server will take care of create new one or update exited one base one that value – sahara108 Dec 16 '15 at 01:39
  • @sahara108 I thought about doing that (that's what I do for Android), but because I need to save the token to know if it was changed, I use the token instead of adding a another stored variable in the keychain. – Kuf Dec 16 '15 at 02:02
  • You only store one variable in both way. The only different thing is that if you have multiple application, you can re-use `identifierForVendor` as it is the same across your app. – sahara108 Dec 16 '15 at 02:26
  • Is this what most providers like Braze are doing? I can't find them specify that in the document. – somenickname May 16 '18 at 13:24