diff --git a/src/routes/docs/apis/realtime/+page.markdoc b/src/routes/docs/apis/realtime/+page.markdoc index 86b52ed7d6..1abc7792ab 100644 --- a/src/routes/docs/apis/realtime/+page.markdoc +++ b/src/routes/docs/apis/realtime/+page.markdoc @@ -12,14 +12,14 @@ This lets you build an interactive and responsive user experience by providing i {% multicode %} ```client-web -import { Client } from "appwrite"; +import { Client, Channel } from "appwrite"; const client = new Client() .setEndpoint('https://.cloud.appwrite.io/v1') .setProject(''); // Subscribe to files channel -client.subscribe('files', response => { +client.subscribe(Channel.files(), response => { if(response.events.includes('buckets.*.files.*.create')) { // Log when a new file is uploaded console.log(response.payload); @@ -37,7 +37,7 @@ final client = Client() final realtime = Realtime(client); // Subscribe to files channel -final subscription = realtime.subscribe(['files']); +final subscription = realtime.subscribe([Channel.files()]); subscription.stream.listen((response) { if(response.events.contains('buckets.*.files.*.create')) { @@ -58,7 +58,7 @@ let client = Client() let realtime = Realtime(client) // Subscribe to files channel -let subscription = realtime.subscribe(channels: ["files"]) { response in +let subscription = realtime.subscribe(channels: [Channel.files()]) { response in if (response.events!.contains("buckets.*.files.*.create")) { // Log when a new file is uploaded print(String(describing: response)) @@ -69,6 +69,7 @@ let subscription = realtime.subscribe(channels: ["files"]) { response in ```client-android-kotlin import io.appwrite.Client import io.appwrite.services.Realtime +import io.appwrite.extensions.Channel val client = Client(context) .setEndpoint("https://.cloud.appwrite.io/v1") @@ -77,7 +78,7 @@ val client = Client(context) val realtime = Realtime(client) // Subscribe to files channel -val subscription = realtime.subscribe("files") { +val subscription = realtime.subscribe(Channel.files()) { if(it.events.contains("buckets.*.files.*.create")) { // Log when a new file is uploaded print(it.payload.toString()); @@ -93,6 +94,102 @@ If you subscribe to a channel, you will receive callbacks for a variety of event [View a list of all available events](/docs/advanced/platform/events). +## Channel helpers {% #channel-helpers %} + +Instead of manually writing channel strings, you can use the `Channel` helper class to build type-safe channel subscriptions. The helper provides a fluent API that makes it easier to construct channel strings and reduces errors. + +{% multicode %} +```client-web +import { Client, Channel } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +// Subscribe to account channel +client.subscribe(Channel.account(), response => { + console.log(response); +}); + +// Subscribe to a specific row +client.subscribe( + Channel.tablesdb('').table('').row(''), + response => { + console.log(response); + } +); +``` + +```client-flutter +import 'package:appwrite/appwrite.dart'; + +final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +final realtime = Realtime(client); + +// Subscribe to account channel +final subscription = realtime.subscribe([Channel.account()]); + +// Subscribe to a specific row +final docSubscription = realtime.subscribe([ + Channel.tablesdb('').table('').row('') +]); +``` + +```client-apple +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + +let realtime = Realtime(client) + +// Subscribe to account channel +let subscription = realtime.subscribe(channels: [Channel.account()]) { response in + print(String(describing: response)) +} + +// Subscribe to a specific row +let docSubscription = realtime.subscribe( + channels: [Channel.tablesdb("").table("").row("")] +) { response in + print(String(describing: response)) +} +``` + +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.services.Realtime +import io.appwrite.extensions.Channel + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + +val realtime = Realtime(client) + +// Subscribe to account channel +val subscription = realtime.subscribe(Channel.account()) { + print(it.toString()) +} + +// Subscribe to a specific row +val docSubscription = realtime.subscribe( + Channel.tablesdb("").table("").row("") +) { + print(it.toString()) +} +``` + +{% /multicode %} + +The `Channel` helper supports all available channels and allows you to: +- Build channels with a fluent, chainable API +- Optionally specify resource IDs (omit IDs to subscribe to all resources) +- Add event filters like `.create()`, `.update()`, or `.delete()` {% info title="Permissions" %} All subscriptions are secured by the [permissions system](/docs/advanced/platform/permissions) offered by Appwrite, meaning a user will only receive updates to resources they have permission to access. @@ -114,13 +211,13 @@ In this example we are subscribing to all updates related to our account by usin {% multicode %} ```client-web -import { Client } from "appwrite"; +import { Client, Channel } from "appwrite"; const client = new Client() .setEndpoint('https://.cloud.appwrite.io/v1') .setProject(''); -client.subscribe('account', response => { +client.subscribe(Channel.account(), response => { // Callback will be executed on all account events. console.log(response); }); @@ -135,7 +232,7 @@ final client = Client() final realtime = Realtime(client); -final subscription = realtime.subscribe(['account']); +final subscription = realtime.subscribe([Channel.account()]); subscription.stream.listen((response) { // Callback will be executed on all account events. @@ -153,7 +250,7 @@ let client = Client() let realtime = Realtime(client) -let subscription = realtime.subscribe(channel: "account") { response in +let subscription = realtime.subscribe(channels: [Channel.account()]) { response in // Callback will be executed on all account events. print(String(describing: response)) } @@ -162,6 +259,7 @@ let subscription = realtime.subscribe(channel: "account") { response in ```client-android-kotlin import io.appwrite.Client import io.appwrite.services.Realtime +import io.appwrite.extensions.Channel val client = Client(context) .setEndpoint("https://.cloud.appwrite.io/v1") @@ -169,7 +267,7 @@ val client = Client(context) val realtime = Realtime(client) -val subscription = realtime.subscribe("account") { +val subscription = realtime.subscribe(Channel.account()) { // Callback will be executed on all account events. print(it.payload.toString()) } @@ -181,18 +279,21 @@ val subscription = realtime.subscribe("account") { You can also listen to multiple channels at once by passing an array of channels. This will trigger the callback for any events for all channels passed. -In this example we are listening to a specific row and all files by subscribing to the `databases..tables..rows.` and `files` channels. +In this example we are listening to a specific row and all files by subscribing to `Channel.tablesdb("").table("").row("")` and `Channel.files()` channels. {% multicode %} ```client-web -import { Client } from "appwrite"; +import { Client, Channel } from "appwrite"; const client = new Client() .setEndpoint('https://.cloud.appwrite.io/v1') .setProject(''); -client.subscribe(['databases..tables..rows.', 'files'], response => { - // Callback will be executed on changes for the specific row and all files. +client.subscribe([ + Channel.tablesdb('').table('').row(''), + Channel.files() +], response => { + // Callback will be executed on changes for the row and all files. console.log(response); }); ``` @@ -206,10 +307,13 @@ final client = Client() final realtime = Realtime(client); -final subscription = realtime.subscribe(['databases..tables..rows.', 'files']); +final subscription = realtime.subscribe([ + Channel.tablesdb('').table('').row(''), + Channel.files() +]); subscription.stream.listen((response) { - // Callback will be executed on changes for the specific row and all files. + // Callback will be executed on changes for the row and all files. print(response); }) ``` @@ -224,8 +328,11 @@ let client = Client() let realtime = Realtime(client) -realtime.subscribe(channels: ["databases..tables..rows.", "files"]) { response in - // Callback will be executed on changes for the specific row and all files. +realtime.subscribe(channels: [ + Channel.tablesdb("").table("").row(""), + Channel.files() +]) { response in + // Callback will be executed on changes for the row and all files. print(String(describing: response)) } ``` @@ -233,14 +340,18 @@ realtime.subscribe(channels: ["databases..tables..rows..cloud.appwrite.io/v1") .setProject("") val realtime = Realtime(client) -realtime.subscribe(listOf("databases..tables..rows.", "files")) { - // Callback will be executed on changes for the specific row and all files. +realtime.subscribe( + Channel.tablesdb("").table("").row(""), + Channel.files() +) { + // Callback will be executed on changes for the row and all files. print(it.toString()) } ``` @@ -253,13 +364,13 @@ If you no longer want to receive updates from a subscription, you can unsubscrib {% multicode %} ```client-web -import { Client } from "appwrite"; +import { Client, Channel } from "appwrite"; const client = new Client() .setEndpoint('https://.cloud.appwrite.io/v1') .setProject(''); -const unsubscribe = client.subscribe('files', response => { +const unsubscribe = client.subscribe(Channel.files(), response => { // Callback will be executed on changes for all files. console.log(response); }); @@ -277,7 +388,7 @@ final client = Client() final realtime = Realtime(client); -final subscription = realtime.subscribe(['files']); +final subscription = realtime.subscribe([Channel.files()]); subscription.stream.listen((response) { // Callback will be executed on changes for all files. @@ -294,7 +405,7 @@ import Appwrite let client = Client() let realtime = Realtime(client) -let subscription = realtime.subscribe(channel: "files") { response in +let subscription = realtime.subscribe(channels: [Channel.files()]) { response in // Callback will be executed on changes for all files. print(response.toString()) } @@ -306,6 +417,7 @@ subscription.close() ```client-android-kotlin import io.appwrite.Client import io.appwrite.services.Realtime +import io.appwrite.extensions.Channel val client = Client(context) .setEndpoint("https://.cloud.appwrite.io/v1") @@ -313,7 +425,7 @@ val client = Client(context) val realtime = Realtime(client) -val subscription = realtime.subscribe("files") { +val subscription = realtime.subscribe(Channel.files()) { // Callback will be executed on changes for all files. print(it.toString()) } @@ -412,88 +524,77 @@ The response will look like this: # Channels {% #channels %} -A list of channels you can subscribe to. Replace `` with your resource ID or use `*` for wildcards. - -## Account {% #account %} +A list of all channels available you can subscribe to. When using `Channel` helpers, leaving an ID blank will subscribe using `*`. {% table %} * Channel +* Channel Helper * Description --- * `account` +* `Channel.account()` * All account related events (session create, name update...) - -{% /table %} - -## Databases {% #databases %} - -{% table %} -* Channel -* Description +--- +* `tablesdb..tables..rows` +* `Channel.tablesdb('').table('').row()` +* Any create/update/delete events to any row in a table --- * `rows` +* `Channel.rows()` * Any create/update/delete events to any row --- -* `databases..tables..rows` -* Any create/update/delete events to any row in a table ---- -* `databases..tables..rows.` -* Any create/update/delete events to a given row -{% /table %} - -## Storage {% #storage %} - -{% table %} -* Channel -* Description +* `tablesdb..tables..rows.` +* `Channel.tablesdb('').table('').row('')` +* Any update/delete events to a given row --- * `files` +* `Channel.files()` * Any create/update/delete events to any file --- +* `buckets..files.` +* `Channel.bucket('').file('')` +* Any update/delete events to a given file of the given bucket +--- * `buckets..files` -* Any create/update/delete events to any file of the given bucket +* `Channel.bucket('').file()` +* Any update/delete events to any file of the given bucket --- -* `buckets..files.` -* Any create/update/delete events to a given file of the given bucket - -{% /table %} - -## Functions {% #functions %} - -{% table %} -* Channel -* Description +* `teams.*` +* `Channel.teams()` +* Any create/update/delete events to any team +--- +* `teams.` +* `Channel.teams()('')` +* Any update/delete events to a given team +--- +* `memberships.*` +* `Channel.membership()` +* Any create/update/delete events to any membership +--- +* `memberships.` +* `Channel.membership('')` +* Any update/delete events to a given membership --- * `executions` -* Any execution event +* `Channel.executions()` +* Any update to executions --- * `executions.` -* Any execution event to a given execution +* `Channel.function().execution('')` +* Any update to a given execution --- * `functions.` +* `Channel.function('')` * Any execution event to a given function {% /table %} -## Teams & Memberships {% #teams %} - -{% table %} -* Channel -* Description ---- -* `teams` -* Any create/update/delete events to any team ---- -* `teams.` -* Any create/update/delete events to a given team ---- -* `memberships` -* Any create/update/delete events to any membership ---- -* `memberships.` -* Any create/update/delete events to a given membership +You can also filter events by appending event methods to the channel helpers: +- `.create()` - Listen only to create events +- `.update()` - Listen only to update events +- `.delete()` - Listen only to delete events -{% /table %} +For example, `Channel.tablesdb('').table('').row('').update()` will only trigger on row updates. # Custom endpoint {% #custom-endpoint %}