Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New ARTPush/getDevicePushDetails method for simplifying push state access #1186

Closed
wants to merge 15 commits into from

Conversation

maratal
Copy link
Collaborator

@maratal maratal commented Oct 10, 2021

This is what I came up with:

  1. Until there are separate server endpoints for getting ARTDevicePushDetails/recipient and ARTPushState, they should be kept in one place (ARTDevicePushDetails).
  2. We should never persist ARTPushState inside ARTLocalDevice, because it has no sense. If you need state - you just request it.

So, the new method is just a wrapper for a simple access to the push state of the local device (which makes sense).

@maratal maratal marked this pull request as draft October 10, 2021 21:41
@maratal maratal linked an issue Oct 10, 2021 that may be closed by this pull request
@maratal maratal marked this pull request as ready for review October 11, 2021 11:20
Copy link
Contributor

@ben-xD ben-xD left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a user gets the local device information for their current device, the state will always be .unknown. It's definitely not 'nice' to do this, but it is an improvement of having it always be null. Would it be better to create a new type, so that we are not using this type for both push admin and normal push?

I have been testing the current changes in Flutter, but that has required some work (fixing serialization, adding buttons and UI to show the state), since this is a new API.

Also, your new getState actually returns a ARTDevicePushDetails in the callback, not just state. Should it be getDeviceDetails instead? This is because you have defined and implemented:

typedef void (^ARTPushStateCallback)(ARTDevicePushDetails *_Nullable details, ARTErrorInfo *_Nullable error);

Source/ARTDevicePushDetails.h Outdated Show resolved Hide resolved
Source/ARTDevicePushDetails.h Outdated Show resolved Hide resolved
Source/ARTDevicePushDetails.m Show resolved Hide resolved
@ben-xD
Copy link
Contributor

ben-xD commented Oct 11, 2021

I've made changes in Ably-Flutter to use this new API. In the screenshot below, you can see state being updated in the UI (see get push state):

Screenshot 2021-10-11 at 15 46 36

Once this work is merged, this feature will probably not be released on Ably-Flutter until after Ably-Java gets it as well. See ably/ably-java#697 We need to update the Ably-Java issue so that the work is consistent with this PR.

Note: In the Flutter interface in my PR, I have called the method getDevicePushDetails, since this is what it is doing, rather than calling it getState. What do you think? @maratal , should you rename it? (In the UI, it still says "push state", because the UI is only showing that state, im not showing the rest of it.)

@maratal
Copy link
Collaborator Author

maratal commented Oct 12, 2021

I've named it getState since it's already inside ARTPush object. Also in case of different server endpoints for state and other push details there will be different data structure in response. So naming it getState will make sense. On the other hand, I'm sure this information (push state and other push details) is stored on the server in the same db record, so having different endpoints seems unnecessary. So probably there will not be different endpoints, thus response structure will stay the same as it's now (ARTDevicePushDetails) and naming this new method getDevicePushDetails is a good idea.

Source/ARTPush.m Outdated
@@ -235,6 +239,16 @@ - (void)deactivate {
}];
}

- (void)getState:(nonnull ARTPushStateCallback)callback {
[_admin.deviceRegistrations get:_rest.device.id callback:^(ARTDeviceDetails *device, ARTErrorInfo *error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, it is using the push admin class, but when I removed the push admin capability from the API key, it stil works. In other words: I did not need push admin. I wonder why this is the case. We should confirm and document if this method requires Push Admin. WDYT?

Copy link
Collaborator Author

@maratal maratal Oct 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I've found out is if the Admin capability got turned off you need to deactivate/activate push on the device to changes to take effect. In my case not only I've lost admin capability, it stops me from doing anything with pushes, even publish them with deviceId with an error:

{
   code = 40160;
   href = "https://help.ably.io/error/40160";
   message = "action not permitted, app = 5****g";
   serverId = "frontend.****";
   statusCode = 401;
} 

WDYT @ben-xD

Copy link
Contributor

@ben-xD ben-xD Oct 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't publish by device ID without push admin, so that makes sense. So in summary, you discovered that this method (& endpoint) requires push admin?

I think this is a feature that we want clients without push-admin to have access to. Perhaps a separate endpoint should be created then?

Copy link
Collaborator Author

@maratal maratal Oct 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't publish by device ID without push admin, so that makes sense. So in summary, you discovered that this endpoint requires push admin?

No, I've discovered that I can't send pushes neither by deviceId not clientId, but that's I guess how it should be.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can only send pushes by messages (with push payload), if you don't have push admin. To send by client ID, you also need push admin.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears like the _admin instance is being used, which would be very confusing

As we can see here in java https://github.com/ably/ably-java/blob/main/lib/src/main/java/io/ably/lib/push/PushBase.java
DeviceRegistrations is on the same level as Admin, and the latter contains nothing except publish method. So I assume ARTPushAdmin in cocoa contains ARTPushDeviceRegistrations and ARTPushChannelSubscriptions by mistake. So I moved it from there into the ARTPush namespace - b6f1eaf
@QuintinWillison @lawrence-forooghian @lukasz-szyszkowski

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved files out of Admin group as well d447d2c

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@QuintinWillison if you are not against these changes please resolve this conversation since Ben started it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lawrence-forooghian could you please take a look and resolve this conversation if you feel it can be. I've not got enough context or time to get involved right now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maratal is your question "can we move deviceRegistrations and channelSubscriptions from ARTPushAdmin to ARTPush"? If so, I think this comment of mine addresses it.

@maratal
Copy link
Collaborator Author

maratal commented Oct 13, 2021

@ben-xD Regarding different type for getDevicePushDetails. It requires removing properties of the new type from an old type, which requires duplicating the request/response code for the same endpoint for the sole purpose of having different type. I still think it's unnecessary.

@ben-xD
Copy link
Contributor

ben-xD commented Oct 20, 2021

@ben-xD Regarding different type for getDevicePushDetails. It requires removing properties of the new type from an old type, which requires duplicating the request/response code for the same endpoint for the sole purpose of having different type. I still think it's unnecessary.

The problem is this endpoint is designed for a wider use case: Push admin. We should have a more restricted endpoint or functionality which allows users to get their device details without push admin.

@jamienewcomb
Copy link
Member

jamienewcomb commented Nov 4, 2021

@maratal have you addressed Bens comment here? or can @lawrence-forooghian now review

@maratal
Copy link
Collaborator Author

maratal commented Nov 10, 2021

ably/specification#26

@maratal
Copy link
Collaborator Author

maratal commented Nov 12, 2021

@ben-xD Should we merge this? (since further fixes are server-side)

@ben-xD
Copy link
Contributor

ben-xD commented Nov 14, 2021

@ben-xD Should we merge this? (since further fixes are server-side)

Nope I think we should wait for the fix to be done. We would be releasing an API to users which doesn't work as expected, which is a bad thing.

@ben-xD
Copy link
Contributor

ben-xD commented Nov 14, 2021

Since the method has been renamed to getDevicePushDetails,the title of the issue and your new replies should stop using getState, opting for getDevicePushDetails instead?

Additionally, the feature spec needs to be updated with this API as well: getDevicePushDetails. This needs to be done asap. It should be done as part of: ably/specification#26

@maratal maratal changed the title New ARTPush/getState method for simplifying push state access New ARTPush/getDevicePushDetails method for simplifying push state access Nov 14, 2021
}
}

+ (ARTPushState)stateFromString:(NSString *)string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably just naming, but I expect to use here values from stateString like ARTPushStateActive, ARTPushStateFailing etc.
Maybe additionally checking these values in this method could be a better idea than renaming this method.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I'm not sure what you are saying here, this method is for obtaining ARTPushState values from strings that came from JSON data. Am I missing something?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so you should rename it to stateFromJsonString.
I meant you have this method:

- (NSString *)stateString {
    switch (_state) {
        case ARTPushStateActive:
            return @"ARTPushStateActive";
        case ARTPushStateFailing:
            return @"ARTPushStateFailing";
        case ARTPushStateFailed:
            return @"ARTPushStateFailed";
        default:
            return @"ARTPushStateUnknown";
    }
}

which also produce strings from ARTPushState and the method name stateFromString is a bit confusing because I don't know "from which string" it creates the ARTPushState

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point b03a251

Copy link
Collaborator

@lawrence-forooghian lawrence-forooghian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should come up with a cross-platform consensus on this before adding this functionality.

I also think we need to decide what we want to do about the still-existing ARTLocalDevice.{state, errorReason} properties, which are still returning nil (which was the original problem described in the linked #1162). Do we want to remove them?

I think https://github.com/ably/docs/issues/1288 would be the best place to discuss this more widely.


@class ARTErrorInfo;

NS_ASSUME_NONNULL_BEGIN

@interface ARTDevicePushDetails : NSObject

@property (nonatomic) NSMutableDictionary<NSString *, NSString *> *recipient;
@property (nullable, nonatomic) NSString *state;
@property (nonatomic) ARTPushState state;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change (string to enum) can be a separate thing, which we should do regardless of how we solve the LocalDevice issue. I've created an issue for it: #1264.

@@ -9,9 +7,6 @@ NS_ASSUME_NONNULL_BEGIN

@interface ARTPushAdminInternal : NSObject <ARTPushAdminProtocol>

@property (nonatomic, readonly) ARTPushDeviceRegistrationsInternal *deviceRegistrations;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving these properties is a change to the public API, and also these properties are described in the features spec; we’d need to update the features spec before making this change and need to make sure we do a new major release of the library afterwards.

@@ -75,13 +77,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)deactivate;

- (void)getDevicePushDetails:(ARTPushStateCallback)callback;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be agreed cross-platform (i.e. via the features spec) before we add it here. I think https://github.com/ably/docs/issues/1288 would be the best place to come to a consensus on this.

@maratal
Copy link
Collaborator Author

maratal commented Jan 20, 2022

I'm closing this PR in favor of upcoming PRs for issues: #1268, #1264 and other issues spawned from this one - ably/specification#25

@maratal maratal closed this Jan 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Read and persist state returned in ARTLocalDevice/ ARTDeviceDetails
6 participants