Realtime API
The Realtime API provides access a continuous, up-to-date flow of your TalkJS data without the need to send repeated requests or open a chat UI.
Preview: The Realtime API is safe to use in production, but it is still a work in progress. If we make changes to these methods in the future, we will continue to support the current version forever. However this backwards compatibility will be undocumented and not exposed in TypeScript type definitions.
Refs
These reference a specific resource in TalkJS, letting you get or set data on that resource.
Refs don't contain any actual data themselves, they just point to a TalkJS resource.
You can get the actual data (a snapshot) by calling .get()
on a ref.
References the user with a given user ID.
Used in all Realtime API operations affecting that user, such as fetching or updating user data, or adding a user to a conversation. Created via Session.user.
createIfNotExists | Creates a user with this ID, or does nothing if a user with this ID already exists. |
get | Fetches a snapshot of the user. |
set | Sets properties of this user. The user is created if a user with this ID doesn't already exist. |
subscribe | Subscribe to this user's state. |
The ID of the referenced user.
Immutable: if you want to reference a different user, get a new UserRef instead.
userRef.createIfNotExists(params): Promise<void>
Creates a user with this ID, or does nothing if a user with this ID already exists.
If the user already exists, this operation is still considered successful and the promise will still resolve.
Parameters
Returns
A promise that resolves when the operation completes. The promise will reject if client-side user syncing is disabled and the user does not already exist.
userRef.get(): Promise<UserSnapshot | null>
Fetches a snapshot of the user.
This contains all of a user's public information. Fetching a user snapshot doesn't require any permissions. You can read the public information of any user. Private information, such as email addresses and phone numbers, aren't included in the response.
Supports Automatic Batching and Cached Fetch
Returns
A snapshot of the user's public attributes, or null if the user doesn't exist.
userRef.set(params): Promise<void>
Sets properties of this user. The user is created if a user with this ID doesn't already exist.
name
is required when creating a user. The promise will reject if you don't provide a name
and the user does not exist yet.
Parameters
Returns
A promise that resolves when the operation completes. The promise will reject if the request is invalid or if client-side user syncing is disabled.
userRef.subscribe(onSnapshot): UserSubscription
Subscribe to this user's state.
Whenever the user's attributes change, onSnapshot
will fire and Subscription.latestSnapshot
will be updated.
Supports Subscription Sharing and Debounced Unsubscribe
Parameters
Returns
A subscription to the user
References the conversation with a given conversation ID, from the perspective of the current user.
Used in all Realtime API operations affecting that conversation, such as fetching or updating conversation attributes. Created via Session.conversation.
createIfNotExists | Creates this conversation if it does not already exist. Adds you as a participant in this conversation, if you are not already a participant. |
get | Fetches a snapshot of the conversation. |
markAsRead | Marks the conversation as read. |
markAsUnread | Marks the conversation as unread. |
message | Get a reference to a message in this conversation |
participant | Get a reference to a participant in this conversation |
send | Sends a message in the conversation |
set | Sets properties of this conversation and your participation in it. |
subscribeMessages | Subscribes to the messages in the conversation. |
The ID of the referenced conversation.
Immutable: if you want to reference a different conversation, get a new ConversationRef instead.
conversationRef.createIfNotExists(params): Promise<void>
Creates this conversation if it does not already exist. Adds you as a participant in this conversation, if you are not already a participant.
If the conversation already exists or you are already a participant, this operation is still considered successful and the promise will still resolve.
Parameters
Returns
A promise that resolves when the operation completes. The promise rejects if you are not already a participant and client-side conversation syncing is disabled.
conversationRef.get(): Promise<ConversationSnapshot | null>
Fetches a snapshot of the conversation.
This contains all of the information related to the conversation and the current user's participation in the conversation.
Returns
A snapshot of the current user's view of the conversation, or null if the current user is not a participant (including if the conversation doesn't exist).
conversationRef.markAsRead(): Promise<void>
Marks the conversation as read.
Returns
A promise that resolves when the operation completes. The promise rejects if you are not a participant in the conversation.
conversationRef.markAsUnread(): Promise<void>
Marks the conversation as unread.
Returns
A promise that resolves when the operation completes. The promise rejects if you are not a participant in the conversation.
conversationRef.message(id): MessageRef
Get a reference to a message in this conversation
Parameters
Returns
conversationRef.participant(user): ParticipantRef
Get a reference to a participant in this conversation
Parameters
the user's ID or a reference to the user
Returns
conversationRef.send(params): Promise<MessageRef>
Sends a message in the conversation
Parameters
Returns
A promise that resolves with a reference to the newly created message. The promise will reject if you are not a participant with write access in this conversation.
conversationRef.set(params): Promise<void>
Sets properties of this conversation and your participation in it.
The conversation is created if a conversation with this ID doesn't already exist. You are added as a participant if you are not already a participant in the conversation.
Parameters
Returns
A promise that resolves when the operation completes. When client-side conversation syncing is disabled, you may only set your notify
property, when you are already a participant. Everything else requires client-side conversation syncing to be enabled, and will cause the promise to reject.
conversationRef.subscribeMessages(onSnapshot): MessageSubscription
Subscribes to the messages in the conversation.
Initially, you will be subscribed to the 10 most recent messages and any new messages. Call loadMore
to load additional older messages.
Whenever a message is edited, a new message is received, or you load more messages, onSnapshot
will fire and Subscription.latestSnapshot
will be updated. loadedAll
is true when the snapshot contains all the messages in the conversation.
The snapshot is null if you are not a participant in the conversation (including when the conversation doesn't exist)
Parameters
Returns
References the user with a given user ID.
Used in all Realtime API operations affecting that user, such as fetching or updating user data, or adding a user to a conversation. Created via Session.user.
delete | Deletes this message, or does nothing if they are already not a participant. |
edit | Edits this message. |
get | Fetches a snapshot of the message. |
The ID of the conversation that the referenced message belongs to.
Immutable: if you want to reference a message from a different conversation, get a new MessageRef from that conversation.
The ID of the referenced message.
Immutable: if you want to reference a different message, get a new MessageRef instead.
messageRef.delete(): Promise<void>
Deletes this message, or does nothing if they are already not a participant.
Deleting a nonexistent message is treated as success, and the promise will resolve.
Returns
A promise that resolves when the operation completes. This promise will reject if you are not a participant in the conversation or if your role does not give you permission to delete this message.
messageRef.edit(params): Promise<void>
Edits this message.
Parameters
Returns
A promise that resolves when the operation completes. The promise will reject if the request is invalid, the message doesn't exist, you're not a participant, or your role does not give you permission to edit this message.
messageRef.get(): Promise<MessageSnapshot | null>
Fetches a snapshot of the message.
Supports Cached Fetch
Returns
A snapshot of the message's attributes, or null if the message doesn't exist, the conversation doesn't exist, or you're not a participant in the conversation.
References a given user's participation in a conversation.
Used in all Realtime API operations affecting that participant, such as joining/leaving a conversation, or setting their access. Created via ConversationRef.participant.
createIfNotExists | Adds the user as a participant, or does nothing if they are already a participant. |
delete | Removes the user as a participant, or does nothing if they are already not a participant. |
edit | Edits properties of a pre-existing participant. If the user is not already a participant in the conversation, the promise will reject. |
get | Fetches a snapshot of the participant. |
set | Sets properties of this participant. If the user is not already a participant in the conversation, they will be added. |
The ID of the conversation the user is participating in.
Immutable: if you want to reference the user in a different conversation, get a new ParticipantRef instead.
The ID of the user who is participating.
Immutable: if you want to reference a different participant, get a new ParticipantRef instead.
participantRef.createIfNotExists(params): Promise<void>
Adds the user as a participant, or does nothing if they are already a participant.
If the participant already exists, this operation is still considered successful and the promise will still resolve.
Supports Automatic Batching
Parameters
Returns
A promise that resolves when the operation completes. The promise will reject if client-side conversation syncing is disabled and the user is not already a participant.
participantRef.delete(): Promise<void>
Removes the user as a participant, or does nothing if they are already not a participant.
Deleting a nonexistent participant is treated as success, and the promise will resolve.
Returns
A promise that resolves when the operation completes. This promise will reject if client-side conversation syncing is disabled.
participantRef.edit(params): Promise<void>
Edits properties of a pre-existing participant. If the user is not already a participant in the conversation, the promise will reject.
Supports Automatic Batching
Parameters
Returns
A promise that resolves when the operation completes. When client-side conversation syncing is disabled, you may only set your notify
property, when you are already a participant. Everything else requires client-side conversation syncing to be enabled, and will cause the promise to reject.
participantRef.get(): Promise<ParticipantSnapshot | null>
Fetches a snapshot of the participant.
This contains all of the participant's public information.
Returns
A snapshot of the participant's attributes, or null if the user is not a participant. The promise will reject if you are not a participant and try to read information about someone else.
participantRef.set(params): Promise<void>
Sets properties of this participant. If the user is not already a participant in the conversation, they will be added.
Supports Automatic Batching
Parameters
Returns
A promise that resolves when the operation completes. When client-side conversation syncing is disabled, you may only set your notify
property, when you are already a participant. Everything else requires client-side conversation syncing to be enabled, and will cause the promise to reject.
Snapshots
When you fetch data for a ref, you get a snapshot. Snapshots contains all the relevant information about a resource, at a specific point in time. If the data changes on the database, old snapshots will not be automatically updated.
A snapshot of a user's attributes at a given moment in time.
Users also have private information, such as email addresses and phone numbers, but these are only exposed on the REST API.
Custom metadata you have set on the user
The unique ID that is used to identify the user in TalkJS
An IETF language tag. For more information, see: Localization.
When locale
is null, the app's default locale will be used
The user's name, which is displayed on the TalkJS UI
An optional URL to a photo that is displayed as the user's avatar
TalkJS supports multiple sets of settings for users, called "roles". Roles allow you to change the behavior of TalkJS for different users. You have full control over which user gets which configuration.
The default message a person sees when starting a chat with this user
A snapshot of a conversation's attributes at a given moment in time.
Also includes information about the current user's view of that conversation, such as whether or not notifications are enabled.
The current user's permission level in this conversation.
The date that the conversation was created, as a unix timestamp in milliseconds.
Custom metadata you have set on the conversation
The ID of the conversation
Whether the conversation should be considered unread.
This can be true even when unreadMessageCount
is zero, if the user has manually marked the conversation as unread.
The date that the current user joined the conversation, as a unix timestamp in milliseconds.
The last message sent in this conversation, or null if no messages have been sent.
The date of the conversation's most recent message, as a unix timestamp in milliseconds.
If no messages have been sent, this will be the date that the conversation was created instead. To show a chronological list of recent conversations, sort by this property.
The current user's notification settings for this conversation.
false
means no notifications, true
means notifications for all messages, and "MentionsOnly"
means that the user will only be notified when they are mentioned with an @
.
Contains the URL of a photo was set using ConversationBuilder.subject.
Contains the conversation subject if it was set using ConversationBuilder.subject.
The number of messages in this conversation that the current user hasn't read.
One or more welcome messages that will display to the user as a SystemMessage
A snapshot of a participant's attributes at a given moment in time.
The level of access this participant has in the conversation.
The date that this user joined the conversation, as a unix timestamp in milliseconds.
When the participant will be notified about new messages in this conversation.
false
means no notifications, true
means notifications for all messages, and "MentionsOnly"
means that the user will only be notified when they are mentioned with an @
.
The user who this Participant Snapshot is referring to
A snapshot of a message's attributes at a given moment in time.
Automatically expanded to include a snapshot of the user that sent the message, and a snapshot of the referenced message, if this message is a reply.
Whether this message was "from a user" or a general system message without a specific sender.
The sender
property is always present for "UserMessage" messages and never present for "SystemMessage" messages.
The main body of the message, as a list of blocks that are rendered top-to-bottom.
Time at which the message was sent, as a unix timestamp in milliseconds
Custom metadata you have set on the message
Time at which the message was last edited, as a unix timestamp in milliseconds. null
if the message has never been edited.
The unique ID that is used to identify the message in TalkJS
Where this message originated from:
- "web" = Message sent via the UI or via ConversationBuilder.sendMessage
- "rest" = Message sent via the REST API's "send message" endpoint - "import" = Message sent via the REST API's "import messages" endpoint - "email" = Message sent by replying to an email notification
The contents of the message, as a plain text string without any formatting or attachments. Useful for showing in a conversation list or in notifications.
A snapshot of the message that this message is a reply to, or null if this message is not a reply.
Only UserMessages can reference other messages. The referenced message snapshot does not have a referencedMessage
field. Instead, it has referencedMessageId
. This prevents TalkJS fetching an unlimited number of messages in a long chain of replies.
A snapshot of the user who sent the message, or null if it is a system message. The user's attributes may have been updated since they sent the message, in which case this snapshot contains the updated data. It is not a historical snapshot.
A snapshot of a message's attributes at a given moment in time.
Automatically expanded to include a snapshot of the user that sent the message. Since this is a snapshot of a referenced message, its referenced message is not automatically expanded, to prevent fetching an unlimited number of messages in a long chain of replies. Instead, contains the referencedMessageId
field.
Referenced messages are always "UserMessage" because you cannot reply to a system message.
The main body of the message, as a list of blocks that are rendered top-to-bottom.
Time at which the message was sent, as a unix timestamp in milliseconds
Custom metadata you have set on the message
Time at which the message was last edited, as a unix timestamp in milliseconds. null
if the message has never been edited.
The unique ID that is used to identify the message in TalkJS
Where this message originated from:
- "web" = Message sent via the UI or via ConversationBuilder.sendMessage
- "rest" = Message sent via the REST API's "send message" endpoint
- "import" = Message sent via the REST API's "import messages" endpoint
- "email" = Message sent by replying to an email notification
The contents of the message, as a plain text string without any formatting or attachments. Useful for showing in a conversation list or in notifications.
The ID of the message that this message is a reply to, or null if this message is not a reply.
Since this is a snapshot of a referenced message, we do not automatically expand its referenced message. The ID of its referenced message is provided here instead.
A snapshot of the user who sent the message. The user's attributes may have been updated since they sent the message, in which case this snapshot contains the updated data. It is not a historical snapshot.
Guaranteed to be set, unlike in MessageSnapshot, because you cannot reference a SystemMessage
Params
These interfaces are used when sending requests.
Parameters you can pass when creating a user.
The user's name which is displayed on the TalkJS UI
Custom metadata you have set on the user. Default = no custom metadata
An array of email addresses associated with the user. Default = no email addresses
An IETF language tag. See the localization documentation Default = the locale selected on the dashboard
An array of phone numbers associated with the user. Default = no phone numbers
An optional URL to a photo that is displayed as the user's avatar. Default = no photo
An object of push registration tokens to use when notifying this user.
Keys in the object have the format 'provider:token_id'
, where provider
is either "fcm"
for Android (Firebase Cloud Messaging), or "apns"
for iOS (Apple Push Notification Service).
Default = no push registration tokens
TalkJS supports multiple sets of settings, called "roles". These allow you to change the behavior of TalkJS for different users. You have full control over which user gets which configuration. Default = the default
role
The default message a person sees when starting a chat with this user. Default = no welcome message
Parameters you can pass when updating a user.
Properties that are undefined
will not be changed. To clear / reset a property to the default, pass null
.
Custom metadata you have set on the user. This value acts as a patch. Remove specific properties by setting them to null
. Default = no custom metadata
An array of email addresses associated with the user. Default = no email addresses
An IETF language tag. See the localization documentation Default = the locale selected on the dashboard
The user's name which will be displayed on the TalkJS UI
An array of phone numbers associated with the user. Default = no phone numbers
An optional URL to a photo which will be displayed as the user's avatar. Default = no photo
An object of push registration tokens to use when notifying this user.
Keys in the object have the format 'provider:token_id'
, where provider
is either "fcm"
for Android (Firebase Cloud Messaging), or "apns"
for iOS (Apple Push Notification Service).
The value for each key can either be true
to register the device for push notifications, or null
to unregister that device.
Setting pushTokens to null unregisters all the previously registered devices.
Default = no push tokens
TalkJS supports multiple sets of settings, called "roles". These allow you to change the behavior of TalkJS for different users. You have full control over which user gets which configuration. Default = the default
role
The default message a person sees when starting a chat with this user. Default = no welcome message
Parameters you can pass when creating a conversation.
Properties that are undefined
will be set to the default.
Your access to the conversation. Default = "ReadWrite" access.
Custom metadata you have set on the conversation. This value acts as a patch. Remove specific properties by setting them to null
. Default = no custom metadata
Your notification settings. Default = true
The URL for the conversation photo to display in the chat header. Default = no photo, show a placeholder image.
The conversation subject to display in the chat header. Default = no subject, list participant names instead.
System messages which are sent at the beginning of a conversation. Default = no messages.
Parameters you can pass when updating a conversation.
Properties that are undefined
will not be changed. To clear / reset a property to the default, pass null
.
Your access to the conversation. Default = "ReadWrite" access.
Custom metadata you have set on the conversation. This value acts as a patch. Remove specific properties by setting them to null
. Default = no custom metadata
Your notification settings. Default = true
The URL for the conversation photo to display in the chat header. Default = no photo, show a placeholder image.
The conversation subject to display in the chat header. Default = no subject, list participant names instead.
System messages which are sent at the beginning of a conversation. Default = no messages.
Parameters you can pass when sending a message
The text to send in the message.
Custom metadata you have set on the user. Default = no custom metadata
The message that you are replying to. Default = not a reply
Parameters you can pass when editing a message.
Properties that are undefined
will not be changed. To clear / reset a property to the default, pass null
.
Custom metadata you have set on the user. This value acts as a patch. Remove specific properties by setting them to null
. Default = no custom metadata
The new text to set as the message body
Parameters you can pass when creating a participant (adding a user to a conversation).
The level of access the participant should have in the conversation. Default = "ReadWrite" access.
When the participant should be notified about new messages in this conversation. Default = true
false
means no notifications, true
means notifications for all messages, and "MentionsOnly"
means that the user will only be notified when they are mentioned with an @
.
Parameters you can pass when updating a participant.
Properties that are undefined
will not be changed. To clear / reset a property to the default, pass null
.
The level of access the participant should have in the conversation. Default = "ReadWrite" access.
When the participant should be notified about new messages in this conversation. Default = ReadWrite
access.
false
means no notifications, true
means notifications for all messages, and "MentionsOnly"
means that the user will only be notified when they are mentioned with an @
.
Subscriptions
When you subscribe to a resource, you get a subscription. Subscription objects store the current state of your subscription, and allow you to unsubscribe.
A subscription to a specific user
unsubscribe | Unsubscribe from this resource and stop receiving updates. |
Resolves when the subscription starts receiving updates from the server.
The current state of the subscription
An object with the following fields:
type
is one of "pending", "active", "unsubscribed", or "error".
When type
is "active", includes latestSnapshot: UserSnapshot | null
. It is the current state of the user, or null if they don't exist.
When type
is "error", includes the error: Error
field. It is a JS Error
object explaining what caused the subscription to be terminated.
Resolves when the subscription permanently stops receiving updates from the server.
This is either because we manually unsubscribed or because the subscription encountered an unrecoverable error.
userSubscription.unsubscribe()
Unsubscribe from this resource and stop receiving updates.
If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
Returns
A subscription to the messages in a specific conversation.
The subscription is 'windowed'. By default, you subscribe to the 10 most recent messages. You can expand this window by calling loadMore
.
unsubscribe | Unsubscribe from this resource and stop receiving updates. |
Resolves when the subscription starts receiving updates from the server.
Expand the window to include older messages
Calling loadMore
multiple times in parallel will still only load one page of messages.
The current state of the subscription
An object with the following fields:
type
is one of "pending", "active", "unsubscribed", or "error".
When type
is "active", includes latestSnapshot
and loadedAll
.
- latestSnapshot: MessageSnapshot[] | null
the current state of the messages in the window, or null if you're not a participant in the conversation
- loadedAll: boolean
true when latestSnapshot
contains all the messages in the conversation
When type
is "error", includes the error
field. It is a JS Error
object explaining what caused the subscription to be terminated.
Resolves when the subscription permanently stops receiving updates from the server.
This is either because we manually unsubscribed or because the subscription encountered an unrecoverable error.
messageSubscription.unsubscribe()
Unsubscribe from this resource and stop receiving updates.
If the subscription is already in the "unsubscribed" or "error" state, this is a no-op.
Returns
Message Content
This section explains how the contents of a message (MessageSnapshot.content
) is structured.
The content of a message is structured as a list of content blocks. These blocks should be rendered in order, top-to-bottom.
1type ContentBlock =2 | TextBlock3 | FileBlock4 | VoiceBlock5 | ImageBlock6 | AudioBlock7 | VoiceBlock8 | LocationBlock;
Each ContentBlock has a type
field that indicates what kind of block it is.
A block of formatted text. Has a list of TextNode
children. Each child is either a plain text string, or an object representing some text with additional formatting.
For example, if the user typed:
> *This first bit* is bold, and *_the second bit_* is bold and italics
Then this would become a Text Block with the structure:
1{2 type: "text",3 children: [4 {5 type: "text",6 children: [7 { type: "bold", children: ["This first bit"] },8 " is bold, and ",9 {10 children: [11 { type: "italic", children: ["the second bit"] }12 ],13 type: "bold",14 },15 " is bold and italics",16 ],17 },18 ],19}
A FileBlock variant for a video attachment, with additional video-specific metadata. You can identify this variant by checking for subtype: "video"
. Includes metadata about the width and height of the video in pixels, and the duration of the video in seconds.
A FileBlock variant for an image attachment, with additional image-specific metadata. You can identify this variant by checking for subtype: "image"
. Includes metadata about the width and height of the image in pixels.
A FileBlock variant for an audio attachment, with additional audio-specific metadata. You can identify this variant by checking for subtype: "audio"
. Includes metadata about the duration of the audio file in seconds.
A FileBlock variant for a voice message attachment, with additional voice-message-specific metadata. You can identify this variant by checking for subtype: "voice"
. Includes metadata about the duration of the voice recording in seconds.
The base FileBlock, used whenever there is no additional metadata for a file.
We will add new FileBlock variants in the future, for example a DocumentBlock
for text documents. This will not be considered a breaking change, so you should not explicitly check for subtype: undefined
in your code.
Instead, treat the base FileBlock as the default, for example:
1if (block.subtype === "video") {2 handleVideoBlock(block);3} else if (block.subtype === "image") {4 handleImageBlock(block);5} else if (block.subtype === "audio") {6 handleAudioBlock(block);7} else if (block.subtype === "voice") {8 handleVoiceBlock(block);9} else {10 handleBaseFileBlock(block);11}
A block showing a location in the world, typically because a user shared their location in the chat.
Inside a TextBlock
, there is a list of TextNode
children. A text node can either be a plain string, or one of a long list of other node types, which add extra formatting and custom behavior to the text.
1type TextNode =2 | string3 | MarkupNode4 | BulletListNode5 | BulletPointNode6 | CodeSpanNode7 | LinkNode8 | AutoLinkNode9 | ActionLinkNode10 | ActionButtonNode11 | CustomEmojiNode12 | MentionNode;
If the text nodes is not a plain string, it will have a type
field indicating what kind of node it is, and either a property text: string
or a property children: TextNode[]
. This will be true for all nodes added in the future as well.
A node that renders its children with a specific style, either *bold*
_italic_
or ~strikethrough~
.
A node that renders its children styled as a bullet-point list.
A node that renders its children as a point in a bullet list.
A node that renders the specified text in an inline code span.
A node that renders its children as a clickable link to the specified URL.
A node that renders the text as a link to the specified URL. Used when user-typed text is turned into a link automatically.
A node that renders its children as a clickable action link which triggers the specified custom action.
A node that renders its children as a clickable action button which triggers the specified custom action.
A node that is used for custom emoji.
A node that is used when a user is mentioned, for example @alice
.
Specifies the ID of the user who was mentioned, which is useful when there are multiple users with the same name.
Performance
The Realtime API has various optimisations to allow you to use it in a simple way, while still getting maximum performance. Our design philosophy is that the "naive solution" should also be best-practice.
To perform a large number of actions at once, you do not need to do anything differently.
There is no getMany
or subscribeMany
method.
Send the actions one at a time, like this:
1for (let i = 0; i < 1000; i++) {2 session.user(`user ${i}`).subscribe(...);3}
The Realtime API is based on websockets, meaning that there is little overhead on each additional call. Unlike HTTP requests, there is no limit to the number of calls you can have in-flight at a time.
Some calls (like UserRef.subscribe
) support "automatic batching" when you send them multiple times in a row.
TalkJS will combines these calls into one batched call which is sent to the backend.
You will get the exact same response as you would if the requests were sent one at a time, except it's faster.
Batching will never change the order that your calls are sent in. This means that if you interleave different kinds of requests:
1session.user("Alice").get();2session.user("Bob").set({ name: "Robert" });3session.user("Bob").get();
Then TalkJS will send these calls one at a time.
If the GET Alice
and GET Bob
requests were combined into a batch, then SET Bob
could not happen in-between the two GET
calls.
In technical terms, when you do a call that supports automatic batching, we wait until the next microtask in the JavaScript event loop before actually sending the call. If you send another call before then, we check to see if the second call can be sent in a batch with the first call. If the two calls are compatible, we combine them into a batch. Otherwise, we send the first call and wait for the next microtask before sending the second call.
There is no subscription.addSnapshotListener
method, where you can attach a new listener to a pre-existing subscription.
So when you want to attach 5 different listeners to a user, you can do:
1for (let i = 0; i < 5; i++) {2 session.currentUser.subscribe(() => console.log(i))3}
This will result in only one subscription on the backend, with your 5 listeners attached to it. We won't officially unsubscribe until all 5 of your subscriptions have unsubscribed.
When you unsubscribe from a subscription, we wait a little bit before officially unsubscribing. This means that if you unsubscribe and then immediately resubscribe, it happens instantly without sending any requests to the backend. For example, if you are subscribed to a user and want to change the callback to something else:
1const subscription = session.currentUser.subscribe(...);23// Later4subscription.unsubscribe();5const subscription2 = session.currentUser.subscribe(...);
This will not trigger any call to the backend, because internally we are still subscribed to currentUser
when you resubscribe.
This is important because staying subscribed is generally much more efficient than subscribing in the first place.
The amount of time the client will stay subscribed is different for each resource.
Simpler resources that change less often (like users) stay subscribed for longer, because being subscribed to something that rarely changes is almost free.
When you fetch a resource that you are subscribed to, we already know the current state without having to ask the backend. This means that the method becomes synchronous and essentially free. For example:
1session.currentUser.subscribe();23// Later4await session.currentUser.get();
This get
call will not trigger any request to the backend and will return the data instantly.
If you know you are going to get
some data repeatedly, consider subscribing to improve performance.