Add realtime queries docs and announcement blog#2746
Add realtime queries docs and announcement blog#2746atharvadeosthale wants to merge 2 commits intomainfrom
Conversation
WalkthroughThis pull request adds documentation and blog content for realtime query filtering capabilities. A new blog post is introduced to announce realtime queries, and the realtime API documentation is expanded with a dedicated "Queries" section. The documentation section includes code examples across four client languages (web, Flutter, Apple, Android), details on supported query methods (equality, comparison, null-check, and logical operators), and response payload specifications. No changes to actual code or public APIs are introduced. Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@src/routes/blog/post/announcing-realtime-queries/`+page.markdoc:
- Line 6: The frontmatter cover image path currently points to the other post's
asset (`/images/blog/announcing-realtime-channel-helpers/cover.png`); update the
cover field in the +page.markdoc frontmatter to reference the correct image for
this realtime-queries post (or, if intentionally reusing that image, add an
inline comment above the cover line explaining reuse and why it’s shared) so the
cover is accurate and clear.
In `@src/routes/docs/apis/realtime/`+page.markdoc:
- Around line 565-601: The subscribe calls are passing Query objects into the
queries parameter which expects a Set<String>; update each Realtime.subscribe
invocation (the three usages where Channel.tablesdb(...).table(...).row() is
used) to convert Query.equal(...) and Query.notEqual(...) to strings by calling
.toString() so queries is a Set<String> (e.g., replace Query.equal("person",
listOf("person1")) with Query.equal(...).toString()), ensuring
payloadType/onSubscribe semantics remain unchanged.
🧹 Nitpick comments (3)
src/routes/blog/post/announcing-realtime-queries/+page.markdoc (1)
50-59: Inconsistent parameter style betweenQuery.equalandQuery.notEqual.Line 50 passes an array
['person1']while Line 59 passes a plain string'person1'. While both may be valid, using a consistent style in the same code example would be clearer for readers.Suggested fix for consistency
- [Query.equal('person', ['person1'])] + [Query.equal('person', 'person1')]Or alternatively, wrap both in arrays.
src/routes/docs/apis/realtime/+page.markdoc (2)
449-451: "Third parameter" description is only accurate for the Web SDK.The Flutter, Apple, and Android examples all use named parameters (
queries:) rather than a positional third argument. Consider rephrasing to something like "passing queries when subscribing" to be SDK-agnostic.Suggested wording
-You can filter realtime events by passing queries as a third parameter when subscribing. Events are filtered server-side based on your queries, so your callback only receives updates that match your conditions. This allows you to use familiar SDK queries like `Query.equal` to automatically filter events instead of filtering manually in your callback. +You can filter realtime events by passing queries when subscribing. Events are filtered server-side based on your queries, so your callback only receives updates that match your conditions. This allows you to use familiar SDK queries like `Query.equal` to automatically filter events instead of filtering manually in your callback.
477-486: Same inconsistency as the blog: array vs string parameter in Query methods.
Query.equalon line 477 uses['person1'](array) whileQuery.notEqualon line 486 uses'person1'(string). This pattern repeats across all four SDK examples. Pick one style for consistency within the same code block.
| title: "Introducing Realtime queries: Server-side event filtering for subscriptions" | ||
| description: Pass SDK queries when subscribing to realtime channels to automatically filter events server-side, so your callbacks only receive the updates you care about. | ||
| date: 2026-02-16 | ||
| cover: /images/blog/announcing-realtime-channel-helpers/cover.png |
There was a problem hiding this comment.
Cover image path references a different blog post.
The cover path /images/blog/announcing-realtime-channel-helpers/cover.png points to the channel-helpers announcement, not this realtime-queries post. If this is intentional reuse, consider adding a comment. Otherwise, update the path to a dedicated cover image.
🤖 Prompt for AI Agents
In `@src/routes/blog/post/announcing-realtime-queries/`+page.markdoc at line 6,
The frontmatter cover image path currently points to the other post's asset
(`/images/blog/announcing-realtime-channel-helpers/cover.png`); update the cover
field in the +page.markdoc frontmatter to reference the correct image for this
realtime-queries post (or, if intentionally reusing that image, add an inline
comment above the cover line explaining reuse and why it’s shared) so the cover
is accurate and clear.
| ```client-android-kotlin | ||
| import io.appwrite.Client | ||
| import io.appwrite.Query | ||
| import io.appwrite.services.Realtime | ||
| import io.appwrite.extensions.Channel | ||
|
|
||
| val client = Client(context) | ||
| .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") | ||
| .setProject("<PROJECT_ID>") | ||
|
|
||
| val realtime = Realtime(client) | ||
|
|
||
| // Subscribe to all updates | ||
| val allVotes = realtime.subscribe( | ||
| Channel.tablesdb("<DATABASE_ID>").table("<TABLE_ID>").row() | ||
| ) { | ||
| print(it.payload.toString()) | ||
| } | ||
|
|
||
| // Subscribe to updates where person equals 'person1' | ||
| val person1Votes = realtime.subscribe( | ||
| Channel.tablesdb("<DATABASE_ID>").table("<TABLE_ID>").row(), | ||
| payloadType = Any::class.java, | ||
| queries = setOf(Query.equal("person", listOf("person1"))) | ||
| ) { | ||
| print(it.payload.toString()) | ||
| } | ||
|
|
||
| // Subscribe to updates where person is not 'person1' | ||
| val otherVotes = realtime.subscribe( | ||
| Channel.tablesdb("<DATABASE_ID>").table("<TABLE_ID>").row(), | ||
| payloadType = Any::class.java, | ||
| queries = setOf(Query.notEqual("person", "person1")) | ||
| ) { | ||
| print(it.payload.toString()) | ||
| } | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Appwrite Kotlin SDK Realtime subscribe method signature queries parameter documentation
💡 Result:
In the Appwrite Android (Kotlin) SDK, Realtime.subscribe has overloads that accept a queries parameter with this signature (simplified to the relevant one):
fun <T> subscribe(
vararg channels: String,
payloadType: Class<T>,
queries: Set<String> = emptySet(),
callback: (RealtimeResponseEvent<T>) -> Unit
): RealtimeSubscriptionSource (SDK implementation): io.appwrite.services.Realtime in sdk-for-android repo. [1]
What queries is
queriesis a set of query strings (the same query-string format produced by Appwrite’sQueryhelpers, e.g.Query.select(...),Query.equal(...), etc.). Appwrite documents queries as “passed … as an array of query strings, which can be generated using theQueryclass.” [2]- If you pass no queries (
emptySet()), the SDK defaults to selecting all attributes by sendingQuery.select(listOf("*")). [1]
What it affects for Realtime
Realtime subscriptions are still based on channels (per the Realtime docs). [3] In the Android SDK, the queries you pass are additionally sent as URL parameters per-channel/per-subscription-slot (implementation detail), and are used to shape/filter what the server returns for that subscription. [1][3]
Example (select only specific fields in the realtime payload):
realtime.subscribe(
"databases.$db.collections.$col.documents",
payloadType = Document::class.java,
queries = setOf(Query.select(listOf("\$id", "title")).toString())
) { event -> /* ... */ }(Uses Query.select as documented.) [2]
Sources: [1] [2] [3]
Add .toString() to Query objects in the queries parameter.
The queries parameter expects a Set<String>, not Query objects. Convert each Query using .toString():
Example fix
queries = setOf(Query.equal("person", listOf("person1")).toString())instead of:
queries = setOf(Query.equal("person", listOf("person1")))Apply this to all three subscribe calls (lines 580, 587, and 594).
🤖 Prompt for AI Agents
In `@src/routes/docs/apis/realtime/`+page.markdoc around lines 565 - 601, The
subscribe calls are passing Query objects into the queries parameter which
expects a Set<String>; update each Realtime.subscribe invocation (the three
usages where Channel.tablesdb(...).table(...).row() is used) to convert
Query.equal(...) and Query.notEqual(...) to strings by calling .toString() so
queries is a Set<String> (e.g., replace Query.equal("person", listOf("person1"))
with Query.equal(...).toString()), ensuring payloadType/onSubscribe semantics
remain unchanged.
Currently based off branch realtime-channel-helper because it has the newest realtime changes, will change to main once the other branch is merged.
Summary by CodeRabbit