I'm using aws-appsync on Node, with redux-persist-node-storage for offline storage (as discussed in #276).
I can make a GraphQL query when online, and then have it available subsequently when offline. However, if I make a query when offline and the requested data hasn't been requested previously, then it isn't available offline.
What is the best way of ensuring I have the most complete and up to date data available in the offline cache, so that any query I make will be available as either the actual value from the data source (when online) or a snapshot from the last time the app was online (when offline)?
I'm using Lambda functions to retrieve the data from DynamoDB and serve it back to the GraphQL API. Will this affect how I'm able to synchronise the offline data with the live database?
Hi @JonathanHolvey
What is the best way of ensuring I have the most complete and up to date data available in the offline cache, so that any query I make will be available as either the actual value from the data source (when online) or a snapshot from the last time the app was online (when offline)?
If you make a query while online, its results will be written to the cache. If you make the query again while offline, you'll get back the cached data for that query.
Basically, you need to make sure you request it at some point, for example, by periodically making the query.
Another thing worth trying is using subscriptions. I am not sure how well they'll work in Node, but it is a good option to have real-time data available
Thanks for the suggestions, @manueliglesias.
I've now implemented a query for all items (with fetchPolicy: 'network-only') when my app starts, so that I have an initial snapshot cached to perform offline requests against.
I've also got a subscription which fires when new items are added via GraphQL mutations. However, the example code doesn't provide a way of merging these two sources of information. The data in the offline cache isn't updated by the subscription.
How can I get the subscription data merged into the offline cache so it can be accessed by my usual GraphQL query? Is there something I can provide as the next option to the observable's subscribe() method that will achieve this?
This is the code I have at the moment, from the example:
client.hydrated().then((hclient) => {
hclient.query({ query: gql(queries.getAllItems), fetchPolicy: 'network-only' })
.catch(console.error)
const observable = hclient.subscribe({ query: gql(subscriptions.itemAdded) })
observable.subscribe({
next: console.log,
complete: console.log,
error: console.error,
})
}).catch(console.error)
I've read about refetching in the Apollo docs, and I thought it might be the solution to my problem.
I now am able to refetch the getAllItems query using the subscription's next callback. This works well, however, it results in unnecessary network usage, as every item is fetched each time one item changes.
I've considered a few ways of making it more efficient, but nothing has worked so far...
getOneItem) to fetch the updated item as the subscription's next callback: The results from getOneItem aren't available from getAllItemsupdate callback on the subscription, which could give access to the store for manual updating: The update callback is only used when the subscription is created.next callback to access the store for manual updating: The next callback doesn't provide a store parameter, and I don't know how to access the store with aws-appsync.update callback with a mutation that only updates the cache: Mutations don't work with fetchPolicy: 'cache-only'getAllItems and getOneItem to find the data I'm after: I'm picking the items I need from the query result using a non-unique key, which can't be used to fetch a unique item when it's updated.readFragment(): I don't know if this would do what I want, and I don't know to access the store with aws-appsync.Success! :tada:
Option 3 can be achieved using client.readQuery() and client.writeQuery() from the Apollo store API. This is what I ended up using. I got a hint from a StackOverflow question, which pointed me in the right direction.
Most helpful comment
Success! :tada:
Option 3 can be achieved using
client.readQuery()andclient.writeQuery()from the Apollo store API. This is what I ended up using. I got a hint from a StackOverflow question, which pointed me in the right direction.