# History ## Channel object The [Realtime `Channel` object](https://ably.com/docs/channels) exposes the following public method to obtain [`Message`](#message) history. ### Methods ### historyHistory `history(Object params?): Promise>` `Task> HistoryAsync(PaginatedRequestParams dataQuery, bool untilAttach = false);` `PaginatedResult history(Param option)` `history(query: ARTRealtimeHistoryQuery?, callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void) throws` `Deferrable history(Hash option) → yields PaginatedResult` Gets a [paginated](#paginated-result) set of historical messages for this channel. #### Parameters | Parameter | Description | Type | |-----------|-------------|------| | paramsoptionquery | an optional object containing the query parametersan optional array containing the query parametersan optional object containing the query parameters | `Object`[`Param[]`](#param)[`PaginatedRequestParams`](#paginated-request-params) | | Parameter | Description | Type | |-----------|-------------|------| | optionquery | an optional set of key value pairs containing the query parametersan optional object containing the query parameters | `Hash``ARTRealtimeHistoryQuery` | | &blockcallback | yields a `PaginatedResult` objectcalled with a [ARTPaginatedResult](#paginated-result)<[ARTMessage](#message)> object or an error | `Block``Callback` | #### `params` parameters`options` parameters`options` parameters`ARTRealtimeHistoryQuery` properties`PaginatedRequestParams` properties | Property | Description | Type | |----------|-------------|------| | start:startstart | Earliest time in milliseconds since the epoch for any messages retrieved.Earliest `Time` or time in milliseconds since the epoch for any messages retrieved.Earliest time in milliseconds since the epoch for any messages retrieved.
_Default: beginning of time_ | `Number``Int` or `Time``Long` | | end:endend | Latest time in milliseconds since the epoch for any messages retrieved.Latest `Time` or time in milliseconds since the epoch for any messages retrieved.Latest time in milliseconds since the epoch for any messages retrieved.
_Default: current time_ | `Number``Int` or `Time``Long` | | direction:directiondirection | `forwards` or `backwards`.`:forwards` or `:backwards`.`forwards` or `backwards`.
_Default: `backwards``:backwards`_ | `String``Symbol` | | limit:limitlimit | Maximum number of messages to retrieve per page, up to 1,000.
_Default: `100`_ | `Number``Integer` | | untilAttach:until_attach | when true, ensures message history is up until the point of the channel being attached. See [continuous history](https://ably.com/docs/storage-history/history#continuous-history) for more info. Requires the `direction` to be `backwards` (the default). If the `Channel` is not attached, or if `direction` is set to `forwards`, this option will result in an error.
_Default: `false`_ | `Boolean` |
| Property | Description | Type | |----------|-------------|------| | Start | Earliest `DateTimeOffset` or time in milliseconds since the epoch for any messages retrieved.
_Default: beginning of time_ | `DateTimeOffset` | | End | Latest `DateTimeOffset` or time in milliseconds since the epoch for any messages retrieved.
_Default: current time_ | `DateTimeOffset` | | Direction | `forwards` or `backwards`.
_Default: `backwards`_ | `Direction` enum | | Limit | Maximum number of messages to retrieve per page, up to 1,000.
_Default: `100`_ | `Integer` | | untilAttach | When true, ensures message history is up until the point of the channel being attached.
_Default: `false`_ | `Boolean` |
#### Returns Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](#paginated-result) encapsulating an array of [`Message`](#message) 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#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 [`Message`](#message) 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`](#error-info) object with the failure reason. #### Returns On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`Message`](#message) 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#ably-exception) #### Returns Returns a `Task` that needs to be awaited. On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`NextAsync`](#paginated-result) and [`FirstAsync`](#paginated-result) methods. Failure to retrieve the message history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception) #### Returns A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) object is returned from the method. On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield a [PaginatedResult](#paginated-result) that encapsulates an array of [`Message`](#message) 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 trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](#error-info) object with the failure reason. ## Presence object [Realtime `Presence` object](https://ably.com/docs/presence-occupancy/presence) exposes the following public method to obtain presence event history such as enter, update and leave events. These events are represented as [`PresenceMessage`](#presence-message) objects. ### Methods ### historyHistory `history(Object params?): Promise>` `Task> HistoryAsync(PaginatedRequestParams query, bool untilAttach = false [deprecated])` `PaginatedResult history(Param[] option)` `history(query: ARTRealtimeHistoryQuery?, callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void) throws` `Deferrable history(Hash option) → yields PaginatedResult` Gets a [paginated](#paginated-result) set of historical presence events for this channel. #### Parameters | Parameter | Description | Type | |-----------|-------------|------| | paramsoptionquery | an optional object containing the query parameters, as specified below. | `Object`[`Param[]`](#param)[`PaginatedRequestParams`](https://ably.com/docs/api/realtime-sdk/history#paginated-request-params) | | Parameter | Description | Type | |-----------|-------------|------| | optionquery | an optional set of key value pairs containing the query parametersan optional object containing the query parameters | `Hash``ARTRealtimeHistoryQuery`[`PaginatedRequestParams`](#paginated-request-params) | | &blockcallback | yields a `PaginatedResult` objectcalled with a [ARTPaginatedResult](#paginated-result)<[ARTPresenceMessage](#presence-message)> object or an error | `Block``Callback` | #### `params` parameters`options` parameters`options` parameters`ARTRealtimeHistoryQuery` properties`PaginatedRequestParams` properties | Property | Description | Type | |----------|-------------|------| | start:startStart | Earliest time in milliseconds since the epoch for any presence events retrieved.Earliest `Time` or time in milliseconds since the epoch for any presence events retrieved.Earliest `DateTimeOffset` or time in milliseconds since the epoch for any presence events retrieved.
_Default: beginning of time_ | `Number``Int` or `Time``Long``DateTimeOffset` | | end:endEnd | Latest time in milliseconds since the epoch for any presence events retrieved.Latest `Time` or time in milliseconds since the epoch for any presence events retrieved.Latest `DateTimeOffset` or time in milliseconds since the epoch for any presence events retrieved.
_Default: current time_ | `Number``Int` or `Time``Long``DateTimeOffset` | | direction:directionDirection | `forwards` or `backwards`.`:forwards` or `:backwards`.
_Default: `backwards``:backwards`_ | `String``Symbol``Direction` enum | | limit:limitLimit | Maximum number of presence events to retrieve up to 1,000.
_Default: `100`_ | `Number``Integer` | | untilAttach:until_attach | when true, ensures presence message history is up until the point of the channel being attached. See [continuous history](https://ably.com/docs/storage-history/history#continuous-history) for more info. Requires the `direction` to be `backwards` (the default). If the `Channel` is not attached, or if `direction` is set to `forwards`, this option will result in an error.
_Default: `false`_ | `Boolean` |
#### Returns Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](#paginated-result) encapsulating an array of [`PresenceMessage`](#presence-message) 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#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 [`PresenceMessage`](#presence-message) 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 presence event history, `err` contains an [`ErrorInfo`](#error-info) object with the failure reason. #### Returns On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`PresenceMessage`](#presence-message) 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 presence event history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception) #### Returns Returns a `Task` that needs to be awaited. On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`PresenceMessage`](#presence-message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`NextAsync`](#paginated-result) and [`FirstAsync`](#paginated-result) methods. Failure to retrieve the presence event history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception) #### Returns A [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) object is returned from the method. On success, the registered success blocks for the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) and any block provided to the method yield a [PaginatedResult](#paginated-result) that encapsulates an array of [`PresenceMessage`](#presence-message) 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 presence event history will trigger the `errback` callbacks of the [`Deferrable`](https://ably.com/docs/api/realtime-sdk/types#deferrable) with an [`ErrorInfo`](#error-info) object with the failure reason. ## Related types ### MessageARTMessageAbly::Models::Message Enumio.ably.lib.types.MessageIO.Ably.Message A `Message` represents an individual message that is sent to or received from Ably. #### Properties | Property | Description | Type | |----------|-------------|------| | name | The event name, if provided. | `String` | | data | The message payload, if provided. | `String`, `StringBuffer`, `JSON Object` | | extras | Metadata and/or ancillary payloads, if provided. Valid payloads include [`push`](https://ably.com/docs/push/publish#payload), `headers` (a map of strings to strings for arbitrary customer-supplied metadata), [`ephemeral`](https://ably.com/docs/pub-sub/advanced#ephemeral), and [`privileged`](https://ably.com/docs/platform/integrations/webhooks#skipping) objects. | `JSON Object` | | id | A Unique ID assigned by Ably to this message. | `String` | | clientId | The client ID of the publisher of this message. | `String` | | connectionId | The connection ID of the publisher of this message. | `String` | | connectionKey | A connection key, which can optionally be included for a REST publish as part of the [publishing on behalf of a realtime client functionality](https://ably.com/docs/pub-sub/advanced#publish-on-behalf). | `String` | | timestamp | Timestamp when the message was first received by the Ably, as milliseconds since the epoch. | `Integer` | | encoding | This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload. | `String` | | action | The action type of the message, one of the [`MessageAction`](https://ably.com/docs/api/realtime-sdk/types#message-action) enum values. | `int enum { MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, META, MESSAGE_SUMMARY }` | | serial | A server-assigned identifier that will be the same in all future updates of this message. It can be used to add annotations to a message. Serial will only be set if you enable annotations in [channel rules](https://ably.com/docs/channels#rules). | `String` | | annotations | An object containing information about annotations that have been made to the object. | [`MessageAnnotations`](https://ably.com/docs/api/realtime-sdk/types#message-annotations) | | Property | Description | Type | |----------|-------------|------| | nameName | The event name, if provided. | `String` | | dataData | The message payload, if provided. | `String`, `ByteArray`, `JSONObject`, `JSONArray``String`, `byte[]`, plain C# object that can be serialized to JSON`String`, `Binary` (ASCII-8BIT String), `Hash`, `Array``NSString *`, `NSData *`, `NSDictionary *`, `NSArray *``String`, `NSData`, `Dictionary`, `Array` | | extrasExtras | Metadata and/or ancillary payloads, if provided. Valid payloads include [`push`](https://ably.com/docs/push/publish#payload), `headers` (a map of strings to strings for arbitrary customer-supplied metadata), [`ephemeral`](https://ably.com/docs/pub-sub/advanced#ephemeral), and [`privileged`](https://ably.com/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray`plain C# object that can be converted to JSON`Hash`, `Array``Dictionary`, `Array``NSDictionary *`, `NSArray *` | | idId | A Unique ID assigned by Ably to this message. | `String` | | client_idClientIdclientId | The client ID of the publisher of this message. | `String` | | connection_idConnectionIdconnectionId | The connection ID of the publisher of this message. | `String` | | connection_keyConnectionKeyconnectionKey | A connection key, which can optionally be included for a REST publish as part of the [publishing on behalf of a realtime client functionality](https://ably.com/docs/pub-sub/advanced#publish-on-behalf). | `String` | | timestampTimestamp | Timestamp when the message was first received by the Ably, as milliseconds since the epocha `Time` objecta `DateTimeOffset``NSDate`. | `Long Integer``DateTimeOffset``Time``NSDate` | | encodingEncoding | This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload. | `String` | ### Message constructors #### Message.fromEncoded `Message.fromEncoded(Object encodedMsg, ChannelOptions channelOptions?) → Message` A static factory method to create a [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) from a deserialized `Message`-like object encoded using Ably's wire protocol. ##### Parameters | Parameter | Description | Type | |-----------|-------------|------| | encodedMsg | a `Message`-like deserialized object. | `Object` | | channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` | ##### Returns A [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) object #### Message.fromEncodedArray `Message.fromEncodedArray(Object[] encodedMsgs, ChannelOptions channelOptions?) → Message[]` A static factory method to create an array of [`Messages`](https://ably.com/docs/api/realtime-sdk/types#message) from an array of deserialized `Message`-like object encoded using Ably's wire protocol. ##### Parameters | Parameter | Description | Type | |-----------|-------------|------| | encodedMsgs | an array of `Message`-like deserialized objects. | `Array` | | channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` | ##### Returns An `Array` of [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) objects ### PresenceMessageARTPresenceMessageAbly::Models::PresenceMessage Enumio.ably.lib.types.PresenceMessageIO.Ably.PresenceMessage A `PresenceMessage` represents an individual presence update that is sent to or received from Ably. #### Properties | Property | Description | Type | |----------|-------------|------| | actionAction | the event signified by a PresenceMessage. See [`PresenceMessage.action`](https://ably.com/docs/api/realtime-sdk/types#presence-action) | `enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``enum { Absent, Present, Enter, Leave, Update }``int enum { ABSENT, PRESENT, ENTER, LEAVE, UPDATE }``enum { :absent, :present, :enter, :leave, :update }``ARTPresenceAction` | | dataData | The presence update payload, if provided | `String`, `ByteArray`, `JSONObject`, `JSONArray``String`, `byte[]`, plain C# object that can be converted to Json`String`, `StringBuffer`, `JSON Object``String`, `Binary` (ASCII-8BIT String), `Hash`, `Array``String`, `NSData`, `Dictionary`, `Array``NSString *`, `NSData *`, `NSDictionary *`, `NSArray *` | | extrasExtras | Metadata and/or ancillary payloads, if provided. The only currently valid payloads for extras are the [`push`](https://ably.com/docs/push/publish#sub-channels), [`ref`](https://ably.com/docs/channels/messages#interactions) and [`privileged`](https://ably.com/docs/platform/integrations/webhooks#skipping) objects. | `JSONObject`, `JSONArray`plain C# object that can be converted to Json`JSON Object``Hash`, `Array``Dictionary`, `Array``NSDictionary *`, `NSArray *` | | idId | Unique ID assigned by Ably to this presence update | `String` | | clientIdclient_idClientIdclientId | The client ID of the publisher of this presence update | `String` | | connectionIdconnection_idConnectionIdconnectionId | The connection ID of the publisher of this presence update | `String` | | timestampTimestamp | Timestamp when the presence update was received by Ably, as milliseconds since the epoch. | `Integer``Long Integer``DateTimeOffset``Time``NSDate` | | encodingEncoding | This will typically be empty as all presence updates received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload | `String` | #### PresenceMessage constructors #### PresenceMessage.fromEncoded `PresenceMessage.fromEncoded(Object encodedPresMsg, ChannelOptions channelOptions?) → PresenceMessage` A static factory method to create a [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types#presence-message) from a deserialized `PresenceMessage`-like object encoded using Ably's wire protocol. ##### Parameters | Parameter | Description | Type | |-----------|-------------|------| | encodedPresMsg | a `PresenceMessage`-like deserialized object. | `Object` | | channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` | ##### Returns A [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types#presence-message) object #### PresenceMessage.fromEncodedArray `PresenceMessage.fromEncodedArray(Object[] encodedPresMsgs, ChannelOptions channelOptions?) → PresenceMessage[]` A static factory method to create an array of [`PresenceMessages`](https://ably.com/docs/api/realtime-sdk/types#presence-message) from an array of deserialized `PresenceMessage`-like object encoded using Ably's wire protocol. ##### Parameters | Parameter | Description | Type | |-----------|-------------|------| | encodedPresMsgs | an array of `PresenceMessage`-like deserialized objects. | `Array` | | channelOptions | an optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data. | `Object` | ##### Returns An `Array` of [`PresenceMessage`](https://ably.com/docs/api/realtime-sdk/types#presence-message) objects ### Presence actionARTPresenceActionio.ably.lib.types.PresenceMessage.ActionAbly::Models::PresenceMessage::ACTIONIO.Ably.PresenceAction `Presence` `action` is a String with a value matching any of the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events). ```javascript var PresenceActions = [ 'absent', // (reserved for internal use) 'present', 'enter', 'leave', 'update' ] ``` `io.ably.lib.types.PresenceMessage.Action` is an enum representing all the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events). ```java public enum Action { ABSENT, // 0 (reserved for internal use) PRESENT, // 1 ENTER, // 2 LEAVE, // 3 UPDATE // 4 } ``` `IO.Ably.PresenceAction` is an enum representing all the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events). ```csharp public enum Action { Absent, // 0 (reserved for internal use) Present, // 1 Enter, // 2 Leave, // 3 Update // 4 } ``` `Ably::Models::PresenceMessage::ACTION` is an enum-like value representing all the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events). `ACTION` can be represented interchangeably as either symbols or constants. #### Symbol states ```ruby :absent # => 0 (reserved for internal use) :present # => 1 :enter # => 2 :leave # => 3 :update # => 4 ``` #### Constant states ```ruby PresenceMessage::ACTION.Absent # => 0 (internal use) PresenceMessage::ACTION.Present # => 1 PresenceMessage::ACTION.Enter # => 2 PresenceMessage::ACTION.Leave # => 3 PresenceMessage::ACTION.Update # => 4 ``` #### Example usage ```ruby # Example with symbols presence.on(:attached) { ... } # Example with constants presence.on(Ably::Models::PresenceMessage::ACTION.Enter) { ... } # Interchangeable Ably::Models::PresenceMessage::ACTION.Enter == :enter # => true ``` `ARTPresenceAction` is an enum representing all the [Realtime Presence states & events](https://ably.com/docs/presence-occupancy/presence#trigger-events). ```objc typedef NS_ENUM(NSUInteger, ARTPresenceAction) { ARTPresenceAbsent, // reserved for internal use ARTPresencePresent, ARTPresenceEnter, ARTPresenceLeave, ARTPresenceUpdate }; ``` ```swift enum ARTPresenceAction : UInt { case Absent // reserved for internal use case Present case Enter case Leave case Update } ``` ### IO.Ably.PaginatedRequestParams `HistoryRequestParams` is a type that encapsulates the parameters for a history queries. For example usage see [`Channel#History`](https://ably.com/docs/api/realtime-sdk/history#channel-history). #### Members | Property | Description | Type | |----------|-------------|------| | Start | The start of the queried interval.
_Default: `null`_ | `DateTimeOffset` | | End | The end of the queried interval.
_Default: `null`_ | `DateTimeOffset` | | Limit | By default it is null. Limits the number of items returned by history or stats.
_Default: `null`_ | `Integer` | | Direction | Enum which is either `Forwards` or `Backwards`.
_Default: `Backwards`_ | `Direction` enum | | ExtraParameters | Optionally any extra query parameters that may be passed to the query. This is mainly used internally by the library to manage paging. | `Dictionary` |
### PaginatedResultARTPaginatedResultAbly::Models::PaginatedResultio.ably.lib.types.PaginatedResultIO.Ably.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/#pagination) is accompanied by metadata that indicates the relative queries available to the `PaginatedResult` object. #### Properties | Property | Description | Type | |----------|-------------|------| | itemsItems | 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 #### firstFirst `first(): Promise` Returns a promise. On success, the promise is fulfilled with a new [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/history#paginated-result) for the first page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected. `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#deferrable) and yields a [PaginatedResult](#paginated-result). `Task> FirstAsync()` Returns a new `PaginatedResult` for the first page of results. The method is asynchronous and returns a Task which needs to be awaited to get the [PaginatedResult](#paginated-result). #### hasNextHasNexthas_next? `Boolean hasNext()` `Boolean HasNext()` `Boolean hasNext()` `Boolean has_next?` Returns `true` if there are more pages available by calling `next``Next` and returns `false` if this page is the last page available. #### isLastIsLastlast? `Boolean isLast()` `Boolean IsLast()` `Boolean isLast()` `Boolean last?` Returns `true` if this page is the last page and returns `false` if there are more pages available by calling `next``Next` available. #### nextNext `next(): Promise` 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#error-info) object that details the reason why it was rejected. `next(callback: (ARTPaginatedResult?, ARTErrorInfo?) → Void)` `PaginatedResult next()` Returns a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `Null``nil``null` is returned. When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types#deferrable) and yields a [PaginatedResult](#paginated-result). `Task> NextAsync()` Returns a new [`PaginatedResult`](https://ably.com/docs/api/realtime-sdk/historypaginated-result) loaded with the next page of results. If there are no further pages, then a blank PaginatedResult will be returned. The method is asynchronous and return a Task which needs to be awaited to get the `PaginatedResult` #### 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#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())); }; ``` ```csharp PaginatedResult firstPage = await channel.HistoryAsync(null); Message firstMessage = firstPage.Items[0]; Console.WriteLine("Page 0 item 0: " + firstMessage.data); if (firstPage.HasNext) { var nextPage = await firstPage.NextAsync(); Console.WriteLine("Page 1 item 1:" + nextPage.Items[1].data); Console.WriteLine("More pages?: " + 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 ``` ```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())") } } ``` ### io.ably.lib.types.Param `Param` is a type encapsulating a key/value pair. This type is used frequently in method parameters allowing key/value pairs to be used more flexible, see [`Channel#history`](https://ably.com/docs/api/realtime-sdk/history#channel-history) for an example. Please note that `key` and `value` attributes are always strings. If an `Integer` or other value type is expected, then you must coerce that type into a `String`. #### Members | Property | Description | Type | |----------|-------------|------| | key | The key value | `String` | | value | The value associated with the `key` | `String` |