# Push Notifications - Admin
## Push Admin object
This object is accessible through `client.push.admin` and provides:
### Push Admin PropertiesPush::Admin Properties
The push admin object exposes the following public propertiesattributesmembers:
#### deviceRegistrationsdevice_registrations
The returned [`DeviceRegistrations`](#device-registrations-object) object provides functionality for registering, updating, listing and de-registering push devices.
#### channelSubscriptionschannel_subscriptions
The returned [`PushChannelSubscriptions`](#push-channel-subscriptions) object provides functionality for subscribing, listing and unsubscribing individual devices or groups of [identified devices](https://ably.com/docs/auth/identified-clients.md) to push notifications published on channels.
### Methods
#### publish
`publish(Object recipient, Object payload): Promise`
`Deferrable publish(Hash recipient, Hash data) → yield`
`publish(recipient=Object, data=Object)`
`publish(recipient: ARTPushRecipient, data: AnyObject?, callback: ((ARTErrorInfo?) -> Void)?)`
`void publish(String recipient, Object data, CompletionListener listener)`
Publishes a push notification directly to a device or group of devices sharing a [client identifier](https://ably.com/docs/auth/identified-clients.md). See the [push notification direct publishing documentation](https://ably.com/docs/push/publish.md#direct-publishing) for more information.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| recipient | Contains the push recipient details. See the [push notification publish REST API documentation](https://ably.com/docs/api/rest-api.md#push-publish) for details on the supported recipient fields | `Object` |
| payloaddata | Contains the push notification data. See the [push admin payload structure](https://ably.com/docs/push/publish.md#payload) for details on the supported push payload fields | `Object` |
| Parameter | Description | Type |
|-----------|------|-------------|
| recipient | Contains the push recipient details. See the [push notification publish REST API documentation](https://ably.com/docs/api/rest-api.md#push-publish) for details on the supported recipient fields | `Hash` |
| data | Contains the push notification data. See the [push admin payload structure](https://ably.com/docs/push/publish.md#payload) for details on the supported push payload fields | `Hash` |
| &block | Yielded upon success | |
| Parameter | Description | Type |
|-----------|------|-------------|
| recipient | Contains the push recipient details. See the [push notification publish REST API documentation](https://ably.com/docs/api/rest-api.md#push-publish) for details on the supported recipient fields | `Object` |
| data | Contains the push notification data. See the [push admin payload structure](https://ably.com/docs/push/publish.md#payload) for details on the supported push payload fields | `Object` |
| listener | Listener to be notified on completion | [`CompletionListener`](#completion-listener) |
| Parameter | Description | Type |
|-----------|------|-------------|
| recipient | Contains the push recipient details. See the [push notification publish REST API documentation](https://ably.com/docs/api/rest-api.md#push-publish) for details on the supported recipient fields | `Object` |
| data | Contains the push notification data. See the [push admin payload structure](https://ably.com/docs/push/publish.md#payload) for details on the supported push payload fields | `Object` |
| callback | Called upon publishing the message, or with an error | |
##### Returns
Returns a promise. On success to publish the push notification, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
The callback is called upon success or failure to publish the push notification. When this operation fails, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and any block provided to the method are yielded to.
Failure to publish the push notification will trigger the `errback` callback of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Listener result
On successful publish of the message, the `onSuccess` method of the [CompletionListener](#completion-listener) is called. On failure to publish the message, the `onError` method is called with an [`ErrorInfo`](#error-info) argument describing the failure reason.
## PushDeviceRegistrations objectDeviceRegistrations object
This object is accessible through `client.push.admin.deviceRegistrations``client.push.admin.device_registrations` and provides an API to register new push notification devices, update existing devices, deregister old devices, and retrieve or list devices registered to an app.
### Methods
#### get
`get(String deviceId): Promise`
`get(DeviceDetails deviceDetails): Promise`
`get(String deviceId) -> yields DeviceDetails`
`get(DeviceDetails device) -> yields DeviceDetails`
`DeviceDetails get(device_id=String)`
`get(DeviceDetails device, callback(ErrorInfo err, DeviceDetails device))`
`get(deviceId: ArtDeviceId, callback: ((ARTDeviceDetails?, ARTErrorInfo?) -> Void))`
`get(DeviceDetails device, callback(ErrorInfo err, DeviceDetails device))`
`DeviceDetails get(String deviceId)`
`getAsync(String deviceId, Callback callback)`
`get(DeviceDetails device, callback(ErrorInfo err, DeviceDetails device))`
Obtain the `DeviceDetails` for a device registered for receiving push registrations matching the `deviceId` argument, or the `id` attribute of the provided `DeviceDetails` object. Requires `push-admin` permission or `push-subscribe` permission together with device authentication matching the requested `deviceId`.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| deviceId | The unique device ID String for the requested device | `String` |
| deviceDetailsdevice | A `DeviceDetails` object containing at a minimum the `deviceId` of the requested device | [`DeviceDetails`](#device-details) |
| Parameter | Description | Type |
|-----------|------|-------------|
| deviceId | The unique device ID String for the requested device | `String` |
| device | A `DeviceDetails` object containing at a minimum the `deviceId` of the requested device | [`DeviceDetails`](#device-details) |
| &block | Yields a `DeviceDetails` object upon success | |
##### Returns
Returns a promise. On success, the promise is fulfilled with a [`DeviceDetails`](#device-details) object representing the device registered for push notifications. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
On success, `device` contains the device registered for push notifications as a [`DeviceDetails`](#device-details) object.
On failure to retrieve the device, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and any block provided to the method yield the device registered for push notifications as a [`DeviceDetails`](#device-details) object.
Failure to retrieve the device will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Listener result
On successful publish of the message, the `onSuccess` method of the [CompletionListener](#completion-listener) is called. On failure to get the device, the `onError` method is called with an [`ErrorInfo`](#error-info) argument describing the failure reason.
#### list
`list(Object params): Promise>`
`Deferrable list(Hash params) → yields PaginatedResult`
`PaginatedResult list(params=Object)`
`list(params: NSDictionary *, callback: ((ARTPaginatedResult?, ARTErrorInfo?) -> Void))`
`PaginatedResult list(Param[] params)`
Retrieve all devices matching the params filter as a paginated list of [`DeviceDetails`](#device-details) objects. Requires `push-admin` permission.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the query parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the query parameters as key value pairs as specified below | `Object` |
| &block | | Yields a `PaginatedResult` object |
##### `params` properties
| Property | Description | Type |
|----------|------|-------------|
| clientId:client_id | Optional filter to restrict to devices associated with that client identifier. Cannot be used with a deviceId:device_id param | `String` |
| deviceId:device_id | Optional filter to restrict to devices associated with that device identifier. Cannot be used with a `clientId``:client_id` param | `String` |
| limit:limit | _100_ maximum number of devices per page to retrieve, up to 1,000 | `Integer` |
| Property | Description | Type |
|----------|------|-------------|
| clientId | Optional filter to restrict to devices associated with that client identifier. Cannot be used with a `deviceId` param | `String` |
| deviceId | Optional filter to restrict to devices associated with that device identifier. Cannot be used with a `clientId` param | `String` |
| limit | _100_ maximum number of devices per page to retrieve, up to 1,000 | `Integer` |
| state | Optional filter by the state of the device. Must be one of `ACTIVE`, `FAILING` or `FAILED` | `String` |
##### Returns
Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) encapsulating an array of [`DeviceDetails`](#device-details) objects corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
On success, `resultPage` contains a [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) encapsulating an array of [`DeviceDetails`](#device-details) objects corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
On failure to retrieve the devices, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and any block provided to the method yield a [PaginatedResult](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) that encapsulates an array of [`DeviceDetails`](#device-details) corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
Failure to retrieve the devices will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
#### save
`save(DeviceDetails deviceDetails): Promise`
`Deferrable save(DeviceDetails device) → yields DeviceDetails`
`DeviceDetails save(DeviceDetails device_details)`
`save(deviceDetails: DeviceDetails, callback: ((DeviceDetails?, ARTErrorInfo?) -> Void))`
`DeviceDetails save(DeviceDetails deviceDetails)`
Register a new `DeviceDetails` object, or update an existing `DeviceDetails` object with the Ably service. Requires `push-admin` permission or `push-subscribe` permission together with device authentication matching the requested `deviceId`.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| deviceDetailsdevice | A `DeviceDetails` object | [`DeviceDetails`](#device-details) |
| Parameter | Description | Type |
|-----------|------|-------------|
| `device` | A `DeviceDetails` object | [`DeviceDetails`](#device-details) |
| `&block` | Yields the new `DeviceDetails` object upon success | |
##### Returns
Returns a promise. On success, the promise is fulfilled with a [`DeviceDetails`](#device-details) object representing the newly registered or updated device. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
On success, `device` contains the newly registered or updated device as a [`DeviceDetails`](#device-details) object.
On failure to create or update the device, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and any block provided to the method yield the newly registered or updated device as a [`DeviceDetails`](#device-details) object.
Failure to create or update the device will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
#### remove
`remove(String deviceId): Promise`
`remove(DeviceDetails deviceDetails): Promise`
`remove(String deviceId)`
`remove(DeviceDetails device) -> yield`
`remove(String device_id)`
`remove(DeviceDetails device_details)`
`remove(deviceDetails: DeviceDetails, callback: ((DeviceDetails?, ARTErrorInfo?) -> Void))`
`remove(deviceDetails: DeviceDetails, callback: ((ARTErrorInfo?) -> Void))`
`DeviceDetails save(DeviceDetails deviceDetails)`
`DeviceDetails save(DeviceDetails deviceDetails)`
Remove a device registered for receiving push registrations that matches the `deviceId` argument, or the `id` attribute of the provided [`DeviceDetails`](#device-details) object. Requires `push-admin` permission or `push-subscribe` permission together with device authentication matching the requested `deviceId`.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| deviceId | The unique device ID String for the device | `String` |
| deviceDetailsdevice | A `DeviceDetails` object containing at a minimum the `deviceId` of the device | [`DeviceDetails`](#device-details) |
| Parameter | Description | Type |
|-----------|------|-------------|
| deviceId | The unique device ID String for the device | `String` |
| device | A `DeviceDetails` object containing at a minimum the `deviceId` of the device | [`DeviceDetails`](#device-details) |
| &block | Yields upon success | |
##### Returns
Returns a promise. On success to delete the device, the promise resolves. Note that a request to delete a device that does not exist will result in a successful operation. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
The callback is called upon success or failure to delete the device. Note that a request to delete a device that does not exist will result in a successful operation.
When this operation fails, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and any block provided to the method are yielded to. Note that a request to delete a device that does not exist will result in a successful operation.
Failure to delete the device will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
#### removeWhereremove_where
`removeWhere(Object params): Promise`
`remove_where(Hash params) -> yield`
`remove_where(params=Object)`
`removeWhere(params: NSDictionary *, callback: (ARTErrorInfo?) -> Void)`
`removeWhere(Param[] params)`
Delete all devices matching the params filter. Requires `push-admin` permission.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the filter parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the filter parameters as key value pairs as specified below | `Object` |
| &block | Yields upon success | |
##### `params` properties
| Property | Description | Type |
|----------|------|-------------|
| clientId:client_id | Optional filter to restrict to devices associated with that client identifier. Cannot be used with a `deviceId``:device_id` param | `String` |
| deviceId:device_id | Optional filter to restrict to devices associated with that device identifier. Cannot be used with a `clientId``:client_id` param | `String` |
##### Returns
Returns a promise. On success to delete the device, the promise resolves. Note that a request that does match any existing devices will result in a successful operation. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
The callback is called upon success or failure to delete the device. Note that a request that does match any existing devices will result in a successful operation.
When this operation fails, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and any block provided to the method are yielded to. Note that a request that does match any existing devices will result in a successful operation.
Failure to delete the device will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
## PushChannelSubscriptions object
This object is accessible through `client.push.admin.channelSubscriptions``client.push.admin.channel_subscriptions` and provides an API to subscribe a push notification device to a channel ensuring it receives any push notifications published in the future on that channel. Additionally, this object allows these subscriptions to be retrieved, listed, updated or removed.
### Methods
#### list
`list(Object params): Promise>`
`Deferrable list(Hash params) -> yields PaginatedResult`
`PaginatedResult list(params=Object)`
`list(params: NSDictionary *, callback: ((ARTPaginatedResult?, ARTErrorInfo?) -> Void))`
`PaginatedResult list(Param[] params)`
Retrieve all push channel subscriptions that match the provided params filter as a paginated list of [`PushChannelSubscription`](#push-channel-subscription) objects. Each [`PushChannelSubscription`](#push-channel-subscription) represents a device or set of devices sharing the same [client identifier](https://ably.com/docs/auth/identified-clients.md) registered to a channel to receive push notifications.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the query parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the query parameters as key value pairs as specified below | `Object` |
| &block | Yields a `PaginatedResult` object | |
##### `params` properties
| Property | Description | Type |
|----------|------|-------------|
| channel:channel | Filter to restrict to subscriptions associated with that `channel` | `String` |
| clientId:client_id | Optional filter to restrict to devices associated with that client identifier. Cannot be used with a deviceId:device_id param | `String` |
| deviceId:device_id | Optional filter to restrict to devices associated with that device identifier. Cannot be used with a clientId:client_id param | `String` |
| limit:limit | _100_ maximum number of channel subscriptions per page to retrieve, up to 1,000 | `Integer` |
##### Returns
Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) encapsulating an array of [`PushChannelSubscription`](#push-channel-subscription) objects corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
On success, `resultPage` contains a [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) encapsulating an array of [`PushChannelSubscription`](#push-channel-subscription) objects corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
On failure to retrieve the channel subscriptions, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object which contains the failure reason.
##### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and any block provided to the method yield a [PaginatedResult](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) that encapsulates an array of [`PushChannelSubscription`](#push-channel-subscription) corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
Failure to retrieve the channel subscriptions will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
#### listChannelslist_channels
`listChannels(Object params): Promise>`
`Deferrable list_channels(Hash params) -> yields PaginatedResult`
`PaginatedResult list_channels(params=Object)`
`listChannels(params: NSDictionary *, callback: ((ARTPaginatedResult?, ARTErrorInfo?) -> Void))`
`PaginatedResult listChannels(Param[] params)`
Retrieve a list of channels that have at least one device [subscribed to push notifications](https://ably.com/docs/push/publish.md#sub-channels) as a paginated list of channel name `String` objects. Requires `push-admin` permission.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the query parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the query parameters as key value pairs as specified below | `Object` |
| &block | Yields a `PaginatedResult` object | |
##### `params` properties
| Property | Description | Type |
|----------|------|-------------|
| limit:limit | _100_ maximum number of channels per page to retrieve, up to 1,000 | `Integer` |
##### Returns
Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) encapsulating an array of channel name `String` values corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
On success, `resultPage` contains a [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) encapsulating an array of channel name `String` values corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
On failure to retrieve the channels, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Returns
A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) object is returned from the method.
On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and any block provided to the method yield a [PaginatedResult](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) that encapsulates an array of channel name `String` values corresponding to the current page of results. [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) supports pagination using [`next()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) and [`first()`](https://ably.com/docs/api/realtime-sdk/types.md#paginated-result) methods.
Failure to retrieve the channels will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
#### save
`save(PushChannelSubscription subscription): Promise`
`save(PushChannelSubscription channel_subscription)`
`PushChannelSubscription save(PushChannelSubscription channel_subscription)`
`save(channelSubscription: PushChannelSubscription, callback: ((PushChannelSubscription?, ARTErrorInfo?) -> Void))`
`PushChannelSubscription save(PushChannelSubscription channelSubscription)`
Subscribe a device or group of devices sharing a [client identifier](https://ably.com/docs/auth/identified-clients.md) for push notifications published on a channel.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| channelSubscriptionsubscriptionchannel_subscription | A `PushChannelSubscription` object | [`PushChannelSubscription`](#push-channel-subscription) |
##### Returns
Returns a promise. On success, the promise is fulfilled with a [`PushChannelSubscription`](#push-channel-subscription) object representing the newly subscribed or updated push channel subscription. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
On success, `channelSubscription` contains the newly subscribed or updated push channel subscription as a [`PushChannelSubscription`](#push-channel-subscription) object.
On failure to create or update the channel subscription, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
#### remove
`remove(PushChannelSubscription subscription): Promise`
`remove(PushChannelSubscription channel_subscription)`
`remove(PushChannelSubscription channel_subscription)`
`remove(channelSubscription: PushChannelSubscription, callback: ((ARTErrorInfo?) -> Void))`
`void remove(PushChannelSubscription channelSubscription)`
Unsubscribe a device or group of devices sharing a [client identifier](https://ably.com/docs/auth/identified-clients.md) from push notifications on a channel. Requires `push-admin` permission or, in the case of a subscription associated with a given `deviceId`, `push-subscribe` permission together with device authentication matching that `deviceId`.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| channelSubscriptionsubscription`channel_subscription` | A `PushChannelSubscription` object | [`PushChannelSubscription`](#push-channel-subscription) |
##### Returns
Returns a promise. On success to unsubscribe, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
The callback is called upon success or failure to unsubscribe. Note that a request to unsubscribe or remove a subscription that does not exist will result in a successful operation.
When this operation fails, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
#### removeWhereremove_where
`removeWhere(Object params): Promise`
`remove_where(Hash params)`
`remove_where(params=Object)`
`removeWhere(params: NSDictionary *, callback: (ARTErrorInfo?) -> Void)`
`removeWhere(Param[] params)`
Delete all push channel subscriptions matching the `params` filter. Requires `push-admin` permission.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| params | An object containing the filter parameters as key value pairs as specified below | `Object`[`Param[]`](#param) |
##### `params` properties
| Property | Description | Type |
|----------|------|-------------|
| channel:channel | Filter to restrict to subscriptions associated with that `channel` | `String` |
| clientId:client_id | Optional filter to restrict to devices associated with that client identifier. Cannot be used with `deviceId``:device_id` param | `String` |
| deviceId:device_id | Optional filter to restrict to devices associated with that device identifier. Cannot be used with `clientId``:client_id` param | `String` |
##### Returns
Returns a promise. On success to unsubscribe, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
The callback is called upon success or failure to unsubscribe. Note that a request to unsubscribe or remove a subscription that does not exist will result in a successful operation.
When this operation fails, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
## Related types
### DeviceDetailsAbly::Models::DeviceDetails
A `DeviceDetails` is a type encapsulating attributes of a device registered for push notifications.
#### Properties
| Property | Description | Type |
|----------|------|-------------|
| id | Unique identifier for the device generated by the device itself | `String` |
| clientIdclient_id | Optional trusted [client identifier](https://ably.com/docs/auth/identified-clients.md) for the device | `String` |
| formFactorform_factor | Form factor of the push device. Must be one of `phone`, `tablet`, `desktop`, `tv`, `watch`, `car` or `embedded``embedded` or `other` | `String` |
| metadata | Optional metadata object for this device. The metadata for a device may only be set by clients with `push-admin` privileges | `Object``Hash` |
| platform | Platform of the push device. Must be one of `ios` or `android``android` or `browser` | `String` |
| deviceSecret | Secret value for the device | `String` |
| push.recipient | Push recipient details for this device. See the [REST API push publish documentation](https://ably.com/docs/api/rest-api.md#message-extras-push) for more details | `Object``Hash` |
| push.state | The current state of the push device being either `Active`, `Failing` or `Failed``ACTIVE`, `FAILING` or `FAILED` | `String` |
| push.errorReasonpush.errorpush.error_reason | When the device's state is failing or failed, this attribute contains the reason for the most recent failure | [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) |
### PushChannelAbly::Models::PushChannel
A `PushChannel` is a property of a [`RealtimeChannel`](https://ably.com/docs/api/realtime-sdk/channels.md#properties) or [`RestChannel`](https://ably.com/docs/api/rest-sdk/channels.md#properties). It provides [push devices](https://ably.com/docs/push.md) the ability to subscribe and unsubscribe to push notifications on channels.
#### Methods
##### subscribeDevice
`subscribeDevice(): Promise`
`subscribeDevice()`
Subscribe your device to the channel's push notifications.
###### Returns
Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### subscribeClient
`subscribeClient(): Promise`
`subscribeClient()`
[Subscribe all devices associated with your device's clientId](https://ably.com/docs/push/publish.md#sub-channels) to the channel's push notifications.
###### Returns
Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### unsubscribeDevice
`unsubscribeDevice(): Promise`
`unsubscribeDevice()`
Unsubscribe your device from the channel's push notifications.
###### Returns
Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### unsubscribeClient
`unsubscribeClient(): Promise`
`unsubscribeClient()`
[Unsubscribe all devices associated with your device's clientId](https://ably.com/docs/push/publish.md#sub-channels) from the channel's push notifications.
###### Returns
Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### listSubscriptions
`listSubscriptions(Record params?): Promise>`
`PaginatedResult listSubscriptions(String deviceId, String clientId, String deviceClientId, String channel)`
`listSubscriptions(deviceId: String?, clientId: String?, deviceClientId: String?, channel: String?, callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
Lists push subscriptions on a channel specified by its channel name (`channel`). These subscriptions can be either be a list of client (`clientId`) subscriptions, device (`deviceId`) subscriptions, or if `concatFilters` is set to `true`, a list of both. This method requires clients to have the [Push Admin capability](push#push-admin). For more information, see `GET main.realtime.ably.net/push/channelSubscriptions` [Rest API](https://ably.com/docs/api/rest-api.md).
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| deviceId | A deviceId to filter by | `String` |
| clientId | A clientId to filter by | `String` |
| deviceClientId | A client ID associated with a device to filter by | `String` |
| params | An optional object containing key-value pairs to filter subscriptions by. Can contain `clientId`, `deviceId` or a combination of both, and a `limit` on the number of subscriptions returned, up to 1,000 | `Record` |
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| deviceId | A deviceId to filter by | `String` |
| clientId | A clientId to filter by | `String` |
| deviceClientId | A client ID associated with a device to filter by | `String` |
| callback | Called with a [`ARTPaginatedResult`](#paginated-result) object containing [`PushChannelSubscription`](https://ably.com/docs/api/realtime-sdk/push-admin.md#push-channel-subscription) objects or an error | Callback |
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| deviceId | A deviceId to filter by | `String` |
| clientId | A clientId to filter by | `String` |
| deviceClientId | A client ID associated with a device to filter by | `String` |
##### Returns
Returns a promise. On success, the promise is fulfilled with [`PaginatedResult`](#paginated-result) which encapsulates an array of [PushChannelSubscription](#push-channel-subscription) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result) and [`first`](#paginated-result) methods. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Callback result
On success, `resultPage` contains a [`PaginatedResult`](#paginated-result) encapsulating an array of [PushChannelSubscription](https://ably.com/docs/api/realtime-sdk/push-admin.md#push-channel-subscription) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
On failure to retrieve message history, `err` contains an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object with the failure reason.
##### Returns
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [PushChannelSubscription](#push-channel-subscription) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result) and [`first`](#paginated-result) methods.
Failure to retrieve the message history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types.md#ably-exception)
### PushChannelSubscriptionARTPushChannelSubscriptionChannelSubscriptionArt::Models::PushChannelSubscription
An `PushChannelSubscription` is a type encapsulating the subscription of a device or group of devices sharing a [client identifier](https://ably.com/docs/auth/identified-clients.md) to a channel in order to receive push notifications.
#### PropertiesMembersAttributes
| Property | Description | Type |
|----------|------|-------------|
| channel | The channel that this push notification subscription is associated with | `String` |
| deviceIddevice_id | The device with this identifier is linked to this channel subscription. When present, `clientId``client_id` is never present | `String` |
| clientIdclient_id | Devices with this [client identifier](https://ably.com/docs/auth/identified-clients.md) are included in this channel subscription. When present, `deviceId``device_id` is never present | `String` |
### PushChannelSubscription constructors
#### PushChannelSubscription.forDevicePushChannelSubscription.for_client
`PushChannelSubscription.forDevice(String channel, String deviceId) -> PushChannelSubscription`
`PushChannelSubscription.for_device(String channel, String device_id) -> PushChannelSubscription`
A static factory method to create a `PushChannelSubscription` object for a channel and single device.
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| channel | Channel name linked to this push channel subscription | `String` |
| deviceIddevice_id | The device with this identifier will be linked with this push channel subscription | `String` |
##### Returns
A [`PushChannelSubscription`](https://ably.com/docs/api/realtime-sdk/types.md#push-channel-subscription) object
#### PushChannelSubscription.forClientPushChannelSubscription.for_client
`PushChannelSubscription.forClient(String channel, String clientId) -> PushChannelSubscription`
`PushChannelSubscription.for_client(String channel, String client_id) -> PushChannelSubscription`
A static factory method to create a `PushChannelSubscription` object for a channel and group of devices sharing a [client identifier](https://ably.com/docs/auth/identified-clients.md).
##### Parameters
| Parameter | Description | Type |
|-----------|------|-------------|
| channel | Channel name linked to this push channel subscription | `String` |
| clientIdclient_id | Devices with this [client identifier](https://ably.com/docs/auth/identified-clients.md) are included in the new push channel subscription | `String` |
##### Returns
A `PushChannelSubscription` object
### PaginatedResultARTPaginatedResultio.ably.lib.types.PaginatedResultAbly::Models::PaginatedResult
A `PaginatedResult` is a type that represents a page of results for all message and presence history, stats and REST presence requests. The response from a [Ably REST API paginated query](https://ably.com/docs/api/rest-api.md#pagination) is accompanied by metadata that indicates the relative queries available to the `PaginatedResult` object.
#### PropertiesMembersAttributes
| Property | Description | Type |
|----------|------|-------------|
| items | Contains the current page of results (for example an Array of [`Message`](#message) or [`PresenceMessage`](#presence-message) objects for a channel history request) | `Array ``List ` |
#### Methods
##### first
`first(): Promise`
`PaginatedResult first`
`PaginatedResult first()`
`PaginatedResult first()`
`first(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
Returns a new `PaginatedResult` for the first page of results. When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and yields a [PaginatedResult](#paginated-result).
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` for the first page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### hasNext
`Boolean hasNext()`
`Boolean has_next?`
`Boolean has_next()`
Returns `true` if there are more pages available by calling `next` and returns `false` if this page is the last page available.
##### isLast
`Boolean isLast()`
`Boolean last?`
`Boolean is_last()`
Returns `true` if this page is the last page and returns `false` if there are more pages available by calling `next` available.
##### next
`next(): Promise`
`PaginatedResult next`
`PaginatedResult next()`
`PaginatedResult next()`
`next(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
Returns a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null``Null``None``nil` is returned. When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types.md#deferrable) and yields a [PaginatedResult](#paginated-result).
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null` is returned. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### current
`current(): Promise`
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` loaded with the current page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types.md#error-info) object that details the reason why it was rejected.
##### Example
```javascript
const paginatedResult = await channel.history();
console.log('Page 0 item 0:' + paginatedResult.items[0].data);
const nextPage = await paginatedResult.next();
console.log('Page 1 item 1: ' + nextPage.items[1].data);
console.log('Last page?: ' + nextPage.isLast());
```
```nodejs
const paginatedResult = await channel.history();
console.log('Page 0 item 0:' + paginatedResult.items[0].data);
const nextPage = await paginatedResult.next();
console.log('Page 1 item 1: ' + nextPage.items[1].data);
console.log('Last page?: ' + nextPage.isLast());
```
```java
PaginatedResult firstPage = channel.history();
System.out.println("Page 0 item 0:" + firstPage.items[0].data);
if (firstPage.hasNext) {
PaginatedResult nextPage = firstPage.next();
System.out.println("Page 1 item 1:" + nextPage.items[1].data);
System.out.println("More pages?:" + Strong.valueOf(nextPage.hasNext()));
};
```
```ruby
# When using the REST sync library
first_page = channel.history
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
next_page = first_page.next
puts "Page 1 item 1: #{next_page.items[1].data}"
puts "Last page?: #{next_page.is_last?}"
end
# When using the Realtime EventMachine library
channel.history do |first_page|
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
first_page.next do |next_page|
puts "Page 1 item 1: #{next_page.items[1].data}"
puts "Last page?: #{next_page.is_last?}"
end
end
end
```
```python
result_page = channel.history()
print 'Page 0 item 0: ' + str(result_page.items[0].data)
if result_page.has_next():
next_page = result_page.next()
print 'Page 1 item 1: ' + str(next_page.items[1].data)
print 'Last page?: ' + str(next_page.is_last())
```
```objc
[channel history:^(ARTPaginatedResult *paginatedResult, ARTErrorInfo *error) {
NSLog(@"Page 0 item 0: %@", paginatedResult.items[0].data);
[paginatedResult next:^(ARTPaginatedResult *nextPage, ARTErrorInfo *error) {
NSLog(@"Page 1 item 1: %@", nextPage.items[1].data);
NSLog(@"Last page?: %d", nextPage.isLast());
}];
}];
```
```swift
channel.history { paginatedResult, error in
guard let paginatedResult = paginatedResult else {
print("No results available")
return
}
print("Page 0 item 0: \((paginatedResult.items[0] as! ARTMessage).data)")
paginatedResult.next { nextPage, error in
guard let nextPage = nextPage else {
print("No next page available")
return
}
print("Page 1 item 1: \((nextPage.items[1] as! ARTMessage).data)")
print("Last page? \(nextPage.isLast())")
}
}
```