ably-cocoa icon indicating copy to clipboard operation
ably-cocoa copied to clipboard

Handle push notification theoretical edge case: when device token is renewed but Ably client doesn't exist

Open ben-xD opened this issue 4 years ago • 1 comments

In Ably-java, there is an ActivationContext with keeps a specific token (DeviceTokenDetails) so that it can update Ably servers with the latest FCM registration token whenever it it is expired/ renewed by Android runtime. Because it has this token, it doesn't need an Ably client (rest/ realtime) to currently exist. The only requirement is that an ably client has been instantiated at least once in the whole lifetime of the app since it was installed (assuming the DeviceTokenDetails doesn't expire). This is because the DeviceTokenDetails will be created saved locally for future use when the ably client doesn't exist yet. In ably-java, you just call

ActivationContext.getActivationContext(this).onNewRegistrationToken(RegistrationToken.Type.FCM, s);

However, in Ably-cocoa, there is no such thing that would update Ably with the latest APNs token when it is renewed. In Ably-cocoa, to provide Ably servers with the APNs device token, a realtime or rest client is needed, using ARTPush.didRegisterForRemoteNotifications withDeviceToken: realtime:. This is bad in 2 ways:

  • It is tedious for developers: after registering for APNs, they must save the deviceToken (in a property) and remember to give it to Ably when they create a realtime/ rest client. It adds complexity when there may be more than 1 Ably client (which client do you use?, does it matter if you give it to both, etc.).
  • It goes against the Apple documentation. According to Configuring Remote Notification Support,

Each time your app launches, it must register with APNs. The methods to use differ according to the platform, but in all cases it works as follows:

Your app asks to be registered with APNs.

On successful registration, APNs sends an app-specific device token to the device.

The system delivers the device to your app by calling a method in your app delegate.

Your app sends the device token to the app’s associated provider

If a new (and different) device token is provided to the device at app launch, Ably will not know about it until a new Ably client and the [ARTPush didRegisterForRemoteNotificationsWithDeviceToken:plugin.didRegisterForRemoteNotificationsWithDeviceToken_deviceToken rest:rest] method is called with the new APNs device token and the rest/ realtime client.

Also, from Configuring Remote Notification Support:

When a device token has changed, the user must launch your app once before APNs can once again deliver remote notifications to the device.

If the device token changes while your app is running, the app object calls the application:didRegisterForRemoteNotificationsWithDeviceToken: delegate method again to notify you of the change.

This is the same behaviour as Android, and I believe was one reason why ActivationContext was implemented in ably-java/ ably-android. paddybyers

TLDR

We do not handle a theoretical edge case: when the device token is changed on iOS but the Ably client has not been created. Theoretically, it can change. I think its debatable if we handle this github issue/ case, because it may never change (this is not well documented). By making ARTPush.didRegisterForRemoteNotifications or similar method which does not require a client, it would be easier for users to implement. It will also be more consistent with ably-java.

┆Issue is synchronized with this Jira Task by Unito

ben-xD avatar Aug 02 '21 11:08 ben-xD

I agree, we should free users from calling ARTPush.didRegisterForRemoteNotifications(withDeviceToken:realtime:) manually.

maratal avatar Nov 27 '21 18:11 maratal