Skip to content

Commit 3092127

Browse files
authored
Add troubleshooting for missing real-time event data (#7955)
1 parent bca62c6 commit 3092127

File tree

1 file changed

+96
-0
lines changed
  • src/pages/[platform]/build-a-backend/data/subscribe-data

1 file changed

+96
-0
lines changed

src/pages/[platform]/build-a-backend/data/subscribe-data/index.mdx

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,102 @@ export default function MyComponent() {
8181

8282
`observeQuery` fetches and paginates through all of your available data in the cloud. While data is syncing from the cloud, snapshots will contain all of the items synced so far and an `isSynced` status of `false`. When the sync process is complete, a snapshot will be emitted with all the records in the local store and an `isSynced` status of `true`.
8383

84+
<Accordion title='Missing real-time events and model fields' headingLevel='4' eyebrow='Troubleshooting'>
85+
86+
If you don't see all of the real-time events and model fields you expect to see, here are a few things to look for.
87+
88+
#### Authorization
89+
90+
The model's [authorization rules](/[platform]/build-a-backend/data/customize-authz/) must grant the appropriate rights to the user.
91+
92+
| Operation | Authorization |
93+
| -- | -- |
94+
| `onCreate` | `read` OR `listen` |
95+
| `onUpdate` | `read` OR `listen` |
96+
| `onDelete` | `read` OR `listen` |
97+
| `observeQuery` | `read` OR (`listen` AND `list`) |
98+
99+
If the authorization rules are correct, also ensure the session is authenticated as expected.
100+
101+
#### Selection Set Parity
102+
103+
All of the fields you expect to see in a real-time update must be present in the selection set of the **mutation** that triggers it. A mutation essentially "provides" the fields via its selection set that the corresponding subscription can then select from.
104+
105+
One way to address this is to use a common selection set variable for both operations. For example:
106+
107+
```ts
108+
// Defining your selection set `as const` ensures the types
109+
// propagate through to the response objects.
110+
const selectionSet = ['title', 'author', 'posts.*'] as const;
111+
112+
const sub = client.models.Blog.observeQuery(
113+
filter: { id: { eq: 'blog-id' } },
114+
selectionSet: [...selectionSet]
115+
).subscribe({
116+
next(data) {
117+
handle(data.items)
118+
}
119+
});
120+
121+
// The update uses the same selection set, ensuring all the
122+
// required fields are provided to the subscriber.
123+
const { data } = await client.models.Blog.update({
124+
id: 'blog-id',
125+
name: 'Updated Name'
126+
}, {
127+
selectionSet: [...selectionSet]
128+
});
129+
```
130+
131+
This works well if all subscriptions to `Blog` require the same subset of fields. If multiple subscriptions are involved with various selection sets, you must ensure that all `Blog` mutations contain the superset of fields from all subscriptions.
132+
133+
Alternatively, you can skip the custom selection sets entirely. The internally generated selection set for any given model is identical across operations by default. The trade-off is that the default selection sets exclude related models. So, when related models are required, you would need to either lazy load them or construct a query to fetch them separately.
134+
135+
#### Related Model Mutations
136+
137+
Mutations do not trigger real-time updates for *related* models. This is true even when the subscription includes a related model in the selection set. For example, if we're subscribed to a particular `Blog` and wish to see updates when a `Post` is added or changed, it's tempting to create a subscribe on `Blog` and assume it "just works":
138+
139+
```ts
140+
// Notice how we're fetching a few `Blog` details, but mostly using
141+
// the selection set to grab all the related posts.
142+
const selectionSet = ['title', 'author', 'posts.*'] as const;
143+
144+
const sub = client.models.Blog.observeQuery(
145+
filter: { id: { eq: 'blog-id' } },
146+
selectionSet: [...selectionSet]
147+
).subscribe({
148+
next(data) {
149+
handle(data.items)
150+
}
151+
});
152+
```
153+
154+
But, mutations on `Post` records won't trigger an real-time event for the related `Blog`. If you need `Blog` updates when a `Post` is added, you must manually "touch" the relevant `Blog` record.
155+
156+
```ts
157+
async function addPostToBlog(
158+
post: Schema['Post']['createType'],
159+
blog: Schema['Blog']['type']
160+
) {
161+
// Create the post first.
162+
await client.models.Post.create({
163+
...post,
164+
blogId: blog.id
165+
});
166+
167+
// "Touch" the blog, notifying subscribers to re-render.
168+
await client.models.Blog.update({
169+
id: blog.id
170+
}, {
171+
// Remember to include the selection set if the subscription
172+
// is looking for related-model fields!
173+
selectionSet: [...selectionSet]
174+
});
175+
}
176+
```
177+
178+
</Accordion>
179+
84180
## Set up a real-time event subscription
85181

86182
Subscriptions is a feature that allows the server to send data to its clients when a specific event happens. For example, you can subscribe to an event when a new record is created, updated, or deleted through the API. Subscriptions are automatically available for any `a.model()` in your Amplify Data schema.

0 commit comments

Comments
 (0)