Skip to content

We do not explain how a client lib should populate LocalDevice.push #25

@lawrence-forooghian

Description

@lawrence-forooghian

What's the issue?

LocalDevice extends DeviceDetails, which has a push: DevicePushDetails property. The features spec does not provide any guidance on how a client library should populate this property for a LocalDevice instance.

(This only applies to LocalDevice instances. A non-LocalDevice instance of DeviceDetails is the result of a call to one of the push admin REST APIs, in which all of these properties will have been populated by the backend.)

Let's look at each of the properties of DevicePushDetails in more detail:

  • errorReason: ErrorInfo? and state: .Active | .Failing | .Failed: I believe these are meant to describe whether the Realtime backend was able to successfully send push notifications to that device.
  • recipient: JsonObject: This describes the parameters that the Realtime backend needs in order to send push notifications to that specific device ("push transport details" as the features spec calls them). Its value is best described by the REST API documentation for the "register a device for receiving push notifications" operation. For example, on iOS, it's { transportType: "apns", deviceToken: <string> }, where deviceToken is a value that was originally provided to the client library by iOS.

What does the features spec imply?

recipient property

The features spec implies, but does not explicitly state, that the LocalDevice.push.recipient property should be populated when the client library receives updated push transport details from its environment (OS, browser, …), and should be used to store these details. This is how the current iOS implementation behaves.

In the features spec, this requirement is primarily implied by (emphasis mine):

  • RSH3a2c:

    If the local device has the necessary push details (registration token, etc.), sends a GotPushDeviceDetails event.

  • RSH3a2d:

    If the local device does not have the necessary push details, it initiates a request to the underlying platform (or otherwise generates them)

  • RSH3d3b:

    On event GotPushDeviceDetails (note that this will only happen on platforms whose push device details, after first set, can change, e. g. FCM’s registration token refresh) … make an asynchronous PATCH HTTP request to /push/deviceRegistrations/:deviceId using the local DeviceDetails ’s push details as body (but only the changed fields

  • RSH8i:

    Each time the library is instantiated, if the LocalDevice has push device details (eg an APNS deviceToken), and if the platform supports it, it must verify the validity of those details (eg by requesting a token from the platform and comparing that with the already-known token).

errorReason and state properties

The features spec makes no mention of how LocalDevice.push.{errorReason, state} should be populated.

Suggested solution

recipient property

We should explicitly document how a client library is expected to populate this property, in line with what’s currently implied. We should also use this opportunity to make sure that the guidance we give about storing push transport details locally is compatible with the advice of client platform vendors, for example Apple’s guidance to “never cache device tokens in local storage” (which I think needs to be interpreted not as “don’t store”, but “make sure to validate your stored data”).

errorReason and state properties

This data is potentially useful for a client library to expose, as described in "When is this useful?" of #26.

We have two options for exposing it:

  1. Explain a process by which the client library fetches this data from the server and uses it to populate these properties. We would also need to design a process for keeping these values up to date.
  2. Remove these properties from the LocalDevice interface, and then describe a mechanism for explicitly fetching this data separately. This would be a (in theory, but not in practice since these properties never did anything useful) breaking change to the public API of the library. We’d also have to find a way to handle the fact that these properties exist in its parent DeviceDetails interface (e.g. remove the inheritance).

My preference would be the latter. I can’t think of a use case that requires this data to be updated in real time, and it would add substantial complexity.

Other conversations / issues

┆Issue is synchronized with this Jira Task by Unito

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions