5

I have a React Native app integrated with Relay and I want to delivery an offline-first experience for users.

So, in the first app launch a placeholder should be shown while data is being loaded. After that, every time the app be launched I want to show the last cached data while a fresh data is loaded.

I found this issue from 2015 and based on eyston's answer I've tried to implement a CacheManager based on relay-cache-manager using the AsyncStorage. With the CacheManager I can save and load relay records from cache but when the network is disabled the app isn't able to show cached data.

Is there any way of use relay cached data while relay is fetching fresh data?

Helielson Santos
  • 231
  • 1
  • 2
  • 10

1 Answers1

5

We have a production app which uses Relay and RealmDB for offline experience. We took a separate approach from CacheManager because CacheManager was not quite ready at that time. We used relay-local-schema for this.

We defined the entire schema required for mobile using relay-local-schema. This could be the same file as what your backend server would be using for defining graphql schema and change the resolve function to resolve the data from realm db. For this we also created schema in realmdb which had nearly same structure as the graphql schema for simplicity of writing data returned by backend server to realmdb. You can also automate generating of this schema by using the graphql introspection query. We defined a custom network layer where we made sure that all Relay queries always touch the local db. In the sendQueries function all queries are resolved with relay-local-schema which gets resolved very fast and react views shows the old data and at same time a network request is made for each request in sendQueries function. On receiving data from network request it is written in realmdb and Relay in-memory is store is also populated with the new data, this automatically refreshes all the react views whose data changed. To write data to Relay in-memory store we used the following undocumented method

Relay.Store.getStoreData().handleQueryPayload(query, response);

You can get query object from request that you receive in sendQueries function using request.getQuery().

Our current implementation is bit tied up with our business logic and hence it is difficult to open source this logic. I'll try to provide a demo app is possible.

meteors
  • 1,747
  • 3
  • 20
  • 40
  • Thank you for your quick response @meteors. I thought about using the relay-local-schema, but I gave up because I didn't like the idea of import the `GraphQLSchema` on my app (The schema is defined in a separated project and I don't want to tie up it). After your response I found the [json-to-graphql-schema](https://github.com/aweary/json-to-graphql) repository. I’ll try to use the json schema used by the babel-relay-plugin. – Helielson Santos Mar 06 '17 at 17:12
  • It would be nice to see your implementation. I know it can be hard to separate your business logic from the code and create a repository with a demo, so I would appreciate if you can create a gist with a sample code of the custom network layer and RealmDB updates. The code doesn’t need to work =D. Anyway, I’ll try the approach with local schema. I’ll update here when I get some progress. – Helielson Santos Mar 06 '17 at 17:12
  • Okay I'll try to add a gist or a demo app soon. – meteors Mar 07 '17 at 04:23
  • Just updating: The `CacheManager` was enough for me. It's able to provide cached data while the NetworkLayer is fetching fresh data. The only delay to app show data is to read it from `AsyncStorage`, what is fast. – Helielson Santos Mar 28 '17 at 18:31