apollographql / apollo-cache-persist

🎏 Simple persistence for all Apollo Cache implementations
MIT License
1.39k stars 118 forks source link

Cache actually does not persist my data #45

Closed duytq94 closed 5 years ago

duytq94 commented 6 years ago

Hi all, first thanks for your watching. I have some issues when use "apollo-cache-persist", hope someone can help.

  1. Follow the docs, I know that if I declare these code,

    const cache = new InMemoryCache({...});
    persistCache({
    cache,
    storage: AsyncStorage,
    });
    const client = new ApolloClient({
    cache,
    ...
    });

    By default, apollo auto persist and restore my data when i query, but in console, it just show [apollo-cache-persist] No stored cache to restore many times although my query is success.

  2. Then I try to use CachePersistor instead to handle manually, it persist and restore my data fine, but in my data, it's empty, so I think variable cache when declare at first (const cache = new InMemoryCache({...})) is the problem, I log this cache and its data always empty although my query is success. Is this variable cache is empty, so CachePersistor can't persist my data? Any idea or maybe a simple code to demo are good to me. Thanks a lot!

jamesreggio commented 6 years ago

Hi @duytq94 — sorry for the slow response.

I'm going to assume from storage: AsyncStorage that you're using this with a React Native app. Let me know if I'm mistaken.

The code you've written above looks correct to me. One problem I've seen before is that developers will initialize two or more instances of new InMemoryCache() (or two or more instances of new ApolloClient). When this happens, the cache persistor ends up attached to a cache that never contains any data. Double-check your code to make sure you're only initializing once. (Perhaps add a console.log statement before each of block of code you pasted above and make sure it only logs once.)

If you pass debug: true into persistCache, apollo-cache-persist should log when it goes to persist the cache. You mentioned that it logs that there's 'No stored cache to persist', but does it ever log anything like 'Persisted cache of size XXX' while your app is running? If it does, the problem may lie with AsyncStorage, and not with apollo-cache-persist.

My last thought is that you may be using trigger: 'background'. If you're using this (which can be helpful for performance on React Native — more info here), you'll need to be sure to send your app to the background to trigger the cache persistence. If you're using the iOS simulator, that means you'll need to press CMD-H to go back to the iOS home screen, and then open your app again, to trigger the cache persistence. If you just press CMD-R to reload your app without doing this, nothing will be persisted, because the app has never gone to the background.

Please let me know if any of this helped — or didn't! — and we can dig deeper.

duytq94 commented 6 years ago

Hi @jamesreggio , thanks for your response. But few problem I can tell you, hope these help.

  1. I just initialize one instance (InMemoryCache, ApolloClient, ...).
  2. About option trigger: 'background', it quite odd, If I set option to 'background' and let my app to background state, it's work, the log tell that '[apollo-cache-persist]', 'Persisted cache of size 2'. But what the number 2 of size mean, 2 kilobyte, 2 byte or something else? And when I turn off network or change fetchPolicy="cache-only" to the query to test, no data can't get from the local.
  3. And with option default ('write') - can't persist data again :( . This is my demo project with very simple (just 1 screen to test - App/Containers/Main/Main.Screen.js). https://github.com/duytq94/test Maybe you can try to clear for help, thanks a lot.
AndreasGalster commented 6 years ago

Hmm ... I have the same issue of the cache not working. I've tried localStorage and sessionStorage so far. The cache actually ends up in the storage but apollo client is not using it ... so in effect the app just fails to retrieve the cached data and everything fails.

The app doesn't give me the "Persistet cache of xxxx" when it launches, though as I said it's actually available in the chosen storage method.

/edit: Sorry, my bad. After setting debug: true it tells me that it actually persisted the cache. However the app still tries to fetch from the API and then fails. So it's not actually using the data that it received / has in the store :/

Does the order in which you apply links matter? Like this:

const httpLinkWithAuthToken = ApolloLink.from([
  middlewareAuthLink,
  retryLink,
  httpLink
]);

See sample gist here: https://gist.github.com/AndreasGalster/50d1e331388288008b556618626e0420

jamesreggio commented 6 years ago

@AndreasGalster, it sounds like everything is working as expected.

If you have persisted, cached data, apollo-cache-persist will restore it and your query will initially resolve with that cached data. If the query is configured to also hit the network (perhaps with fetchPolicy: 'cache-and-network) and it gets an error, the error should be passed up to your app, and the results should be cleared.

If you want to ignore errors, you can use an errorPolicy of all or ignore.

And yes, the order of Apollo Links does matter, but it seems like your links are in a reasonable ordering.

lokey commented 6 years ago

@duytq94 I had a similar issue where log says 'Persisted cache of size 2'. But nothing is actually persisted. It seems to be caused by importing ApolloClient from apollo-boost. I fixed it by changing my import to import { ApolloClient } from 'apollo-client';

duytq94 commented 6 years ago

Thanks @lokey I'll check it again.

wtrocki commented 5 years ago

@duytq94 Since Apollo boost is out of the way this issue may no longer be relevant. Can you confirm?