Closed evelant closed 4 years ago
Not everyone is using React let alone React Native. I use Ember.js with Apollo, for example, and plan to use Offix with Ember.js as well.
Is there a simple way to support this feature for React Native without introducing a dependency on React Native libraries?
That is why I opened the issue here. I'm not sure how to have easier react native setup without adding a dependency. Perhaps just putting this snippet into the docs would be sufficient?
I would vote for adding it to the docs. (Note: I'm not the maintainer, just an outside opinion).
If the configuration gets more complicated than that, another idea is to create a separate integration library to handle some of the setup that is specific to React Native. For example, this is what ember-apollo-client does for Ember + Apollo integration, and you could probably do something similar for React Native + Offix integration.
@AndrewMorsillo Thank so much for contribution and logging issue. We were thinking about adding official support for react native and providing sample app that will demo all cases. I will add this to roadmap!
I think we can create separate package for react native that will wrap create client and supply react native based dependencies + it will have RNNetworkStatus and AsyncStore connected to config out of the box. Do you have time to drop this 2 files into new package? I will be really happy to assist with that, release package etc. but it will be nice to see if resulting package will be working in your app.
Additionally, I will refactor current config to decouple cordova integration and provide a similar package for cordova. After this is done documentation will have separate chapters for each platform and we will avoid having if inside the package.
We do not have any example application now for the React Native so looking for a community for input and end to end testing the package.
@AndrewMorsillo I have created new empty package to help with collaboration #24
@AndrewMorsillo Did you get any success with running React Native.
We have done lots of improvements inside the package and extended our interface so it should work flawlessly with the React Native, however, we do not have any sample app provided yet. If you know any sample React Native app that uses Apollo GraphQL please let us know. We can extend it with offix and see if we require additional package or docs.
I'm sorry to say my attention has been taken away from apollo/graphql as my team has decided to instead use Firebase to prototype our new project. I may have time to come back to this in the future but in the near term I won't have any time to look into it.
Perfect! Thank you for getting back. We will still invest time into getting the React Native in future so stay tunned for updates!
I have used the following config and it throws error when I try to execute offline mutation.
React Native 0.60.4
- Android
@alk831 Hi. Do you think it will be possible to provide more details on how this is being setup? Console log might have more information on why this failed. We going to work on sample react native application
@alk831 Do you use Apollo boost? You might find this issue useful: https://github.com/apollographql/apollo-cache-persist/issues/52
I have managed to replicate this issue in https://github.com/wtrocki/offix-react-native-sample and working on checking why this is happening.
Moving from react
to @react-native-community/async-storage
removed the issue.
Leaving this open as we need to add more production-ready examples of how to react native integration will be done.
Sorry for the delay, since I have decided to use sqlite database, as my app will strongly rely on offline mode.
I have been using AsyncStorage
from community package and I still had this issue. It was probably caused by using incorrect client, since I have created it from ApolloClient
(apollo-boost) and your example shows that client is being returned from offix's init promise
.
Actually problem was that storage interface on save expected objects where react native expects string. I needed to create extra wrapper like here:
https://github.com/wtrocki/offix-react-native-sample/blob/master/offixapp/App.js#L12-L21
After that app is fully usable, however, I'm not satisfied enough to close this topic. I think we need to
We going to focus on this in near future (docs especially) with package and sample app to follow.
Can I use offix
with react-native now or it still in development ?
@marceloavf Yes. Take look at sample application (really rough one) @mmusil would document support soon so we will have that in docs.
Really nice work put in here @wtrocki, I was a little worried about using Apollo for a most time offline project done with react-native, but seing those package codes made me happy, thank you!
We are working now on major improvements to library that will also affect react native.
I've been on the GraphQL bandwagon for a while, and came across Offix, which looks very promising indeed. I tried using Offix with react-native, and experienced the "apollo-cache-persist" bug (above) that @alk831 found.
I'm keen to keep the app inside Expo, so the fix to use '@react-native-community/async-storage' won't work, as Expo provides AsyncStorage from 'react-native'. I didn't want to duplicate efforts as @wtrocki has indicated major improvements in the last message above.
Should I standby for imminent support for Expo react-native?
Also, how would I add an API key for the graphql endpoint? This is usually done as an AuthLink like below, but currently I'm hacking \offix-client\dist\LinksBuilder.js#createCompositeLink by adding:
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
"x-api-key": "API_KEY_HERE"
}
};
});
links.push(authLink);
@anfen For auth - you can pass terminating link (http link have headers property). see https://github.com/aerogear/offix/blob/master/docs/ref-release-notes.md#ability-to-customize-apollo-link-chain
The actual storage package do not matter that much. To support react-native AsyncStorage (as an opposed community) the same code can be used in app: https://github.com/wtrocki/offix-react-native-sample/blob/master/offixapp/App.js#L12-L21
What we need to do is to officially document this feature and we holding off as our docs needs to be rewritten.
CC @darahayes
@anfen For auth - you can pass terminating link (http link have headers property). see https://github.com/aerogear/offix/blob/master/docs/ref-release-notes.md#ability-to-customize-apollo-link-chain
The actual storage package do not matter that much. To support react-native AsyncStorage (as an opposed community) the same code can be used in app: https://github.com/wtrocki/offix-react-native-sample/blob/master/offixapp/App.js#L12-L21
What we need to do is to officially document this feature and we holding off as our docs needs to be rewritten.
CC @darahayes
Thanks for the auth explanation, and responding so quick. I tried the AsyncStorage example you referred to, but it returned an error, so I thought I would wait for the major improvements you mentioned.
I can try it again and report back with what I find. Before I do, how far are you with the improvements... should I hold off until then? I'm happy to contribute if there is a need (I'm a react/react-native dev).
Actually having error will be really helpfull. I'm not big fan of expo so having supported both expo and rn-cli will be awesome. Once we have it we can instantly add them to docs and close this issue.
Worth to note. Our React native support is the same as: https://github.com/apollographql/apollo-cache-persist/ support and their docs can be used to validate it.
I'm going to sound like a broken record, so apologies... "how far are you with the major improvements you mentioned" :)
I'd love to contribute, and Expo has come a long way, but I don't want to fix something that you may be working on.
@anfen This is completely unrelated. We are going to release new major change next week, however for both ReactNative support will not change - this will be just oportunity to improve documentation and add some platforms
tab that will have:
@anfen This is completely unrelated. We are going to release new major change next week, however for both ReactNative support will not change - this will be just oportunity to improve documentation and add some
platforms
tab that will have:
- Web
- Ionic/Capacitor
- React Native
Fantastic news. I will identify the Expo\react-native issue, and report back. Have a good weekend!
I used the code from here https://github.com/wtrocki/offix-react-native-sample/blob/master/offixapp/App.js#L12-L21 to test OfflineClient with react-native\Expo.
The storage part of the code uses:
import AsyncStorage from '@react-native-community/async-storage';
but Expo must use:
import { AsyncStorage } from 'react-native';
The result causes data corruption during setItem(), by saving a stringified object with a prop for each letter\number of the data being saved e.g.:
{"0":"{","1":"\"","2":"F","3":"a","4":"c","5":"t","6":":","7":"6","8":"d","9":"8","10":"6","11":"e","12":"5","13":"7","14":"1","15":"-","16":"e","17":"2","18":"a","19":"4","20":"-","21":"4","22":"5","23":"9","24":"8","25":"-","26":"a","27":"e","28":"5","29":"2","30":"-","31":"0","32":"d","33":"b","34":"b","35":"b","36":"8","37":"b","38":"1","39":"0","40":"b","41":"7","42":"3","43":"\"","44":":","45":"{","46":"\"","47":"","48":"","49":"t","50":"y","51":"p","52":"e","53":"n","54":"a","55":"m","56":"e","57":"\"","58":":","59":"\"","60":"F","61":"a","62":"c","63":"t","64":"\"","65":",","66":"\"","67":"i","68":"d","69":"\"","70":":","71":"\"","72":"6","73":"d","74":"8","75":"6","76":"e","77":"5","78":"7","79":"1","80":"-","81":"e","82":"2","83":"a","84":"4","85":"-","86":"4","87":"5","88":"9","8...
(You can make out Fact:6d86e... if you read every other prop, as the data being saved is Fact:UUID etc.)
I've added a "FIX:" comment below which does resolve this, but may not be the correct solution, as it hardcodes returning an object if a string was saved:
const client = new OfflineClient({
terminatingLink: concat(authLink, httpLink),
storage: {
getItem: async (key) => {
const data = await AsyncStorage.getItem(key);
if (typeof data === 'string') //FIX: Required to prevent data becoming corrupt and bloated
return JSON.parse(data);
return data;
},
setItem: async (key, value) => {
let valueStr = value;
if (typeof valueStr === 'object') {
valueStr = JSON.stringify(value);
}
return AsyncStorage.setItem(key, valueStr);
},
}
});
(Sorry about the formatting, the code snippet wouldn't work across the whole code block for some reason) Let me know if you need me to try any changes.
Amazing work. I think we need to simply document that use case. I have created separate hacktoberfest issue so you can just put all this information into our docs and get t-shirt for it.
see https://github.com/aerogear/offix/issues/219
EDIT: Fixed formatting by adding ```js
Update on this. We have provided docs and example application for react native.
I have found wrappers that will work with both expo and react cli.
Docs: https://offix.dev/docs/next/react-native
This is pointing to master. We going to land it in 0.12.0 release
It looks like there are just a couple little missing pieces to work with react native. I'm not sure exactly how to integrate them properly into the codebase so I will put the snippets here. We just need a NetworkStatus implementation and to pass AsyncStorage for the storage engine when creating the client. IMO these should just be defaults when react native is the environment.
Detecting react-native
React native network status implementation
Config for react native
edit: oops it looks like AsyncStorage might not be just drop in. Types don't line up but I think it will work regardless.