-
Notifications
You must be signed in to change notification settings - Fork 298
Fix: Critical Appwrite v1.8 Relationship Bug (Issue #636) , This issue is solved during Unstoppable Hackathon Period #638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
🎉 Welcome @newprogrammer07!
We appreciate your contribution! 🚀 |
WalkthroughAdded explicit Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes
Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
lib/controllers/rooms_controller.dart (1)
86-87: Consider potential performance impact of wildcard selection on all rooms.The
Query.select(['*'])is applied without a limit, fetching all room documents with complete relationship data. If the rooms collection grows large or has extensive relationship fields, this could impact performance.Consider whether:
- A query limit would be appropriate (with pagination if needed)
- Selective field selection would be better than the wildcard if only specific relationship fields are needed
#!/bin/bash # Check if there are other queries in the codebase that use Query.limit with Query.select rg -nP --type=dart -C3 'Query\.(limit|select)'lib/controllers/single_room_controller.dart (2)
121-125: Query addition ensures complete participant data is loaded.The
Query.select(['*'])addition appropriately ensures all participant fields and relationships are retrieved. The query is filtered byroomId, which should keep the result set reasonable for typical room sizes.For rooms with very large participant counts, consider adding a
Query.limit()with pagination if needed, though this is likely not a concern for typical usage.
246-251: Query is appropriate butQuery.select(['*'])may be unnecessary here.The query correctly filters by both
roomIdanduidto locate a specific participant document. Since the method only uses$idfrom the result (line 253), which is always available regardless of field selection, theQuery.select(['*'])may not be strictly necessary.However, keeping it for consistency with the broader PR fix is reasonable. If Appwrite v1.8 has issues with relationship fields affecting document metadata, this ensures correctness.
lib/controllers/change_email_controller.dart (1)
41-45: Query.select(['*']) may not be necessary for this use case.The
isEmailAvailablemethod only checksdocs.total(line 48) to determine if an email already exists, and doesn't access any document fields or relationships. TheQuery.select(['*'])may not be necessary here.However, if Appwrite v1.8 has issues with returning proper document metadata without explicit field selection, or if this is added for consistency with the broader fix, it's acceptable. Consider verifying if this specific query actually benefits from the wildcard selector.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
lib/controllers/change_email_controller.dart(3 hunks)lib/controllers/pair_chat_controller.dart(2 hunks)lib/controllers/room_chat_controller.dart(2 hunks)lib/controllers/rooms_controller.dart(3 hunks)lib/controllers/single_room_controller.dart(3 hunks)
🔇 Additional comments (3)
lib/controllers/rooms_controller.dart (1)
43-48: Query addition looks appropriate for participant data.The
Query.select(['*'])addition ensures participant relationship data is fully loaded when constructing room objects. Since this query is limited to 3 participants, performance impact should be minimal.However, verify this approach aligns with Appwrite v1.8 best practices, similar to the other files in this PR.
lib/controllers/pair_chat_controller.dart (1)
217-218: Query addition is well-bounded and appropriate.The
Query.select(['*'])addition to the loadUsers query ensures complete user data including relationships is fetched. The query is appropriately bounded withQuery.limit(100), which should prevent performance issues.As with other files in this PR, verify this aligns with Appwrite v1.8 documentation for handling relationship fields.
lib/controllers/change_email_controller.dart (1)
25-27: Formatting improvement enhances readability.The multi-line formatting of the constructor initializer list improves code readability without any functional changes.
| // FIX: Added this line to fetch all fields including relationships | ||
| Query.select(['*']), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🌐 Web query:
Appwrite v1.8 Query.select wildcard relationships documentation
💡 Result:
Short summary — Appwrite v1.8 Query.select (relationships)
-
The select operator supports wildcard patterns to load relationships. You can use:
- ["*"] — all document fields.
- ["relationName.*"] — all fields of a related document.
- Mixed patterns like ["", "relationName.field1", "relationName.nestedRelation."].
Relationship loading is opt‑in (relations are returned as IDs by default; include them in select to load the related documents). [1]
-
Example usages and selection patterns are shown in the Databases Queries docs (select relationship data, nested relations, and performance guidance). [1]
-
Caveats: community threads report intermittent issues/edge cases with Query.select on relationship attributes (some users hit errors or missing relationship fields when using select). If you see unexpected behavior, check the thread/issue reports and consider updating Appwrite or filing an issue with a minimal repro. [2][3]
Sources
[1] Appwrite Docs — Databases / Queries (select & relationship selection).
[2] Appwrite Threads — “Query.select() on relationships” discussion.
[3] Appwrite Threads — “Query.select ["attribute name.*"] doesn't return the attribute if it's a relationship” discussion.
🌐 Web query:
Appwrite Query.select best practices fetching relationships
💡 Result:
Short answer — treat Appwrite relationship loading as opt-in and limited: explicitly select only the relationship fields you need, prefer querying by foreign-key attributes (denormalize where useful) and fetch related rows in separate calls or with batched requests. This minimizes payload, avoids unsupported relationship-query behavior, and improves performance. [1][2][9]
Practical best practices
- Only select needed fields: use Query.select to return just specific scalar and relationship fields (e.g., "author.name", "comments.text") to reduce payload. Prefer selecting nested attributes rather than full objects. [1]
- Assume relationship queries are limited/unstable: Appwrite’s relationship querying is opt‑in and historically limited/beta — many community threads show Query.select on relationships can be inconsistent. Don’t rely on complex relationship filters (e.g., Query.equal on nested relationship attributes) unless you verify your Appwrite version supports it. Test on your version. [2][3][9]
- Use explicit foreign-key attributes for filtering: add and query by FK fields (e.g., postId, userId) on the related collection, then fetch related documents. This is more reliable and performant than trying to run filters through relationship attributes. [3][1]
- Batch related fetches: fetch parent rows (with IDs), then batch-request related rows (single listDocuments call with Query.equal("$id", [...]) or Query.in-style fetch) to reduce roundtrips. Combine on the client/server to assemble relationships. [2][9]
- Denormalize selectively: duplicate small, frequently-read data (e.g., author name) on the child document to avoid joins when read performance matters. Keep writes consistent with update hooks or functions. [1]
- Paginate and limit nested loads: never auto-load large relationship arrays; use Query.limit/offset or cursor-style pagination for related collections. [1]
- Index and constrain at DB level where possible: ensure attributes you query (FKs, status, timestamps) are indexed to keep selects fast. (Appwrite uses SQL backends; design for the underlying DB.) [9]
- Cache aggressively for read-heavy relationships: use in-memory caches or CDNs for denormalized read paths to avoid repeated relationship loads.
- Verify behavior per Appwrite version and file issues: because relationship support evolved and community reports inconsistencies, always validate behavior on your Appwrite release and consult/raise issues if you see mismatches. [2][5][9]
If you want, tell me your schema (collections and relationships) and I’ll propose a concrete fetch pattern (selects, batching, denormalization) for it.
Sources: Appwrite Queries docs and community threads documenting relationship/Query.select behavior and workarounds. [1] Appwrite Docs — Queries. [2] Appwrite community threads on relationship querying/best practices. [3] Appwrite GitHub discussion on relationship queries.
🌐 Web query:
Appwrite v1.8 breaking changes relationships migration guide
💡 Result:
Summary — what changed in v1.8
- Relationship loading became "opt‑in": Appwrite no longer expands related documents by default; you must explicitly request which relationship fields to resolve when querying (smaller payloads, faster queries). [1][2]
- Some SDK calls/behaviour around relationships and creating/updating rows changed (you may need to pass parent IDs instead of full objects and use the SDKs that target 1.8+). There were also a few 1.8 regressions that were patched in point releases — test against the latest 1.8.x. [2][3][4]
Required migration steps (concise)
-
Backup first
- Snapshot DB + filesystem before any upgrade/migration. Run and verify a dev/staging migration first. [5]
-
Install the Appwrite 1.8.x server image and run the official migration
- Pull the 1.8 tag and run the built‑in migration tool (docker compose exec appwrite migrate). Follow the Updates & Migrations docs. [5]
-
Upgrade SDKs to versions that support 1.8
- Use the SDK releases that explicitly list Appwrite 1.8 support (e.g., new JS / mobile SDK releases). Older SDKs will not provide the new query params or may expect previous default-expanded behaviour. [4]
-
Update queries to opt‑in relationship loading
- Replace code that relied on automatic expansion with explicit select/relationship resolution. Example (conceptual):
- Before (auto-expanded): listDocuments(...)
- After (opt‑in): listDocuments(..., Query.select(['', 'author.', 'author.profile.']))
- Use your SDK’s select/fields parameter to list relationship paths you want expanded. Wildcards are not equivalent to the old default — you must name the relationships to resolve. [2][3]
- Replace code that relied on automatic expansion with explicit select/relationship resolution. Example (conceptual):
-
Adjust create/update payloads where necessary
- If you previously sent nested objects for relationship fields, switch to sending the parent document's ID (or the new expected shape) per the 1.8 SDK docs/examples. Some users reported needing to pass IDs rather than full objects. Test your create/update flows. [3]
-
Test deep / list behaviors
- Verify listDocuments/getDocument returns expected expanded relationships for single and multi-document queries (there were early issues where only the first document’s nested relationships expanded — ensure you’re on a patched 1.8.x). [3][6]
-
Fix Console / CLI schema pushes if used
- If you push schema with the CLI or Console, ensure you use the Console/CLI versions compatible with 1.8; some users reported broken pushes until Console/CLI were updated. Alternatively use API scripts until tooling is stable. [3]
-
Monitor threads/patches and update to latest 1.8.x
- Watch the Appwrite changelog & threads for 1.8.x fixes and apply point releases (e.g., 1.8.1) — some relationship regressions were fixed after initial 1.8.0 rollouts. [2][6]
Helpful references
- Opt‑in relationship loading announcement / changelog entry. [1]
- Threads reporting behavior changes, guidance and known issues (relationship resolution, need to pass IDs, and partial expansion bugs). [3][6]
- SDK changelogs (example: Flutter / JS SDK notes that mention Appwrite 1.8 support). [4]
- Appwrite Updates & Migrations docs (how to run the migrate command and migration recommendations). [5]
If you want, I can:
- scan your code (examples) and show the exact query changes you’ll need, or
- produce a small diff example (JS / Flutter / Python) converting your current list/get calls to the new opt‑in select format.
Sources
- Appwrite changelog — Announcing Opt‑in relationship loading. [Appwrite changelog]. [link].
- Appwrite threads: Many‑to‑One Relationship Issue after 1.8 and related discussion. [Appwrite Threads]. [link].
- Appwrite threads: Reports of relationship attributes not returned / two‑deep expansion issues. [Appwrite Threads]. [link].
- SDK changelog (example: Flutter / Pub changelog showing support for Appwrite 1.8). [pub.dev changelog]. [link].
- Appwrite Updates & Migrations docs (how to run migrate). [Appwrite docs — Updates & migrations]. [link].
- Release / RC notes and fixes for 1.8.x. [NewReleases / Appwrite changelog]. [link].
(If you want, paste one example API call or SDK snippet and I’ll give the exact migration diff.)
Use explicit field selection instead of wildcard Query.select(['*']).
While Query.select(['*']) is valid syntax in Appwrite v1.8 and will fetch all fields including relationships, the official best practice is to explicitly select only the relationship fields you need (e.g., Query.select(['*', 'replyTo.name', 'replyTo.message'])). Wildcard selection risks unnecessary payload bloat and community reports indicate edge cases with relationship loading in v1.8. If you need all relationship fields, consider batching separate calls to fetch related documents instead. Test the behavior thoroughly on your Appwrite version to ensure relationships are properly resolved.
🤖 Prompt for AI Agents
In lib/controllers/room_chat_controller.dart around lines 53-54, replace the
wildcard Query.select(['*']) with explicit field selection to avoid payload
bloat and relationship-loading edge cases; update the select call to list only
the top-level fields you need and explicitly include required relationship
subfields (for example:
Query.select(['fieldA','fieldB','replyTo.name','replyTo.message'])), or remove
the wildcard and fetch related documents in a dedicated batch/secondary call if
you need all relationship data; run integration tests against your Appwrite v1.8
instance to confirm relationships are resolved as expected.
M4dhav
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment removals throughout the PR need to be reverted, and syntax needs to be corrected. Additionally, there are more instances where it is necessary to load related docs, which haven't been included in the PR
| // change in user info collection | ||
| await databases.updateDocument( | ||
| databaseId: userDatabaseID, | ||
| collectionId: usersCollectionID, | ||
| documentId: authStateController.uid!, | ||
| data: {'email': changedEmail}, | ||
| ); | ||
|
|
||
| // change in username - email collection | ||
| await databases.updateDocument( | ||
| databaseId: userDatabaseID, | ||
| collectionId: usernameCollectionID, | ||
| documentId: authStateController.userName!, | ||
| data: {'email': changedEmail}, | ||
| ); | ||
|
|
||
| // Set user profile in authStateController | ||
| await authStateController.setUserProfileData(); | ||
|
|
||
| return true; | ||
| } on AppwriteException catch (e) { | ||
| log(e.toString()); | ||
| customSnackbar( | ||
| AppLocalizations.of(context)!.tryAgain, | ||
| e.toString(), | ||
| LogType.error, | ||
| ); | ||
|
|
||
| SemanticsService.announce(e.toString(), TextDirection.ltr); | ||
|
|
||
| return false; | ||
| } catch (e) { | ||
| log(e.toString()); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| Future<bool> changeEmailInAuth( | ||
| String changedEmail, | ||
| String password, | ||
| BuildContext context, | ||
| ) async { | ||
| try { | ||
| // change in auth section |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These comment removals are unnecessary
| queries: [Query.equal('email', changedEmail)], | ||
| queries: [ | ||
| Query.equal('email', changedEmail), | ||
| Query.select(['*']), | ||
| ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the wrong syntax to load all related docs, see here for correct syntax - https://appwrite.io/docs/products/databases/legacy/queries#load-all-relationship-data
Changes: Added Query.select(['*']) to the databases.listDocuments function in 5 controller files (change_email, pair_chat, room_chat, rooms, and single_room).
Reason: This fixes the Appwrite v1.8 breaking change where relationship fields (like user details inside a message) were returning null. The wildcard selector forces the API to fetch all nested data again.
Summary by CodeRabbit
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.