Open wimvdb opened 4 years ago
It might be unrelated to the token. The error I'm getting is "errorMessage": "AMQJS0007E Socket error:undefined." similar as in issue #286
But I don't have ws as a dependency in my package.json:
"dependencies": {
"@react-native-community/datetimepicker": "^1.0.0",
"@react-native-community/netinfo": "^4.6.1",
"AsyncStorage": "^0.1.5",
"apollo-cache-inmemory": "^1.6.3",
"apollo-link": "^1.2.13",
"apollo-link-context": "^1.0.19",
"apollo-link-error": "^1.1.12",
"apollo-link-state": "^0.4.2",
"apollo-utilities": "^1.3.2",
"array.prototype.flatmap": "^1.2.2",
"aws-appsync": "^2.0.2",
"aws-appsync-react": "^2.0.2",
"buffer": "^5.4.3",
"email-validator": "^2.0.4",
"graphql": "^14.5.8",
"graphql-tag": "^2.10.1",
"i18n-js": "^3.5.0",
"jest-extended": "^0.11.2",
"jest-mock-console": "^1.0.0",
"json-server": "^0.15.1",
"libphonenumber-js": "^1.7.29",
"mitt": "^1.2.0",
"nanoid": "^2.1.7",
"react": "^16.12.0",
"react-apollo": "^2.5.8",
"react-fast-compare": "^2.0.4",
"react-native": "0.60.4",
"react-native-app-auth": "^4.4.0",
"react-native-app-settings": "^2.0.1",
"react-native-contacts": "^5.0.4",
"react-native-device-info": "^2.3.2",
"react-native-elements": "^1.2.7",
"react-native-exception-handler": "^2.10.8",
"react-native-gesture-handler": "^1.5.2",
"react-native-iap": "^4.3.0",
"react-native-image-picker": "^1.1.0",
"react-native-mixpanel": "^1.1.10",
"react-native-mock-render": "^0.1.7",
"react-native-permissions": "^2.0.6",
"react-native-phone-input": "^0.2.4",
"react-native-picker-select": "^6.3.3",
"react-native-simple-toast": "^0.1.1",
"react-native-splash-screen": "^3.2.0",
"react-native-swipeout": "^2.3.6",
"react-native-vector-icons": "^6.6.0",
"react-native-version": "^3.2.0",
"react-navigation": "^3.13.0",
"redux": "^4.0.4",
"redux-persist": "^4.10.2",
"rn-fetch-blob": "^0.10.16",
"sinon": "^7.5.0"
}
npm ls ws
├─┬ jest-environment-enzyme@7.1.2
│ └─┬ jest-environment-jsdom@24.8.0
│ └─┬ jsdom@11.12.0
│ └── ws@5.2.2
└─┬ react-native@0.60.4
├─┬ @react-native-community/cli@2.8.3
│ ├─┬ metro@0.54.1
│ │ ├─┬ metro-inspector-proxy@0.54.1
│ │ │ └── ws@1.1.5
│ │ └── ws@1.1.5
│ └── ws@1.1.5
└─┬ react-devtools-core@3.6.3
└── ws@3.3.3
I was able to work around the network error by upgrading to aws-appsync 3.0.2 but I'm still have troubles establishing a stable subscription my updated code now looks like this:
export function Cards(props) {
React.useEffect(() => {
Cards.unsubscribeNetWorkChanges = subscribeToNetWorkChanges(subscribeToCardUpdatesFunction);
return () => {
if (Cards.unsubscribeCardUpdates) {
Cards.unsubscribeCardUpdates();
}
if (Cards.unsubscribeNetWorkChanges) {
Cards.unsubscribeNetWorkChanges();
}
}
}, []);
const subscribeToCardUpdatesFunction = () => {
if (props.accountId) {
if (Cards.unsubscribeCardUpdates) {
Cards.unsubscribeCardUpdates()
}
Cards.unsubscribeCardUpdates = props.subscribeToMore({
document: CardSubscriptionGraphQL,
variables: {
ownerId: props.accountId,
},
onError: (error) => {
console.log(error)
trackEvent('Subscription error', error);
}
});
} else {
trackEvent('accountId not set');
}
}
return (
<CardsPage cards={props.cards} />
);
}
export const mapCardsProps = (props) => {
return {
cards: props.data?.cards?.items,
accountId: props.data?.account?.id,
subscribeToMore: props.data.subscribeToMore,
};
};
export default graphql(AccountAndCardsGraphQL, selectConfig(mapCardsProps))(Cards);
export const subscribeToNetWorkChanges = (functionToExecute) => {
return NetInfo.addEventListener((netState) => handleSubscribeOnNetworkChange(netState, functionToExecute));
};
const handleSubscribeOnNetworkChange = (netState, functionToExecute) => {
if (netState.isConnected && netState.isInternetReachable) {
console.log('netState.isConnected && internet')
try {
functionToExecute()
} catch (error) {
trackEvent('Error in handleSubscribeOnNetworkChange', error);
}
}
};
What i'm trying to do is if the network drops I want to unsubscribe and re-subscribe once the internet connection becomes stable again. This works on the simulator. If I disable the internet and re-enable it again I can see the subscription working again when the internet is back. I was expecting the onError to trigger at some point by that does not seem to happen.
When I try to do the same thing on a real device by enabling "flight mode" and then disabling "flight mode" again the re-subscribe is not working. The subscription is not receiving updates. It usually fails quietly but sometimes I get this error:
Cannot read property 'subscriptionFailedCallback' of undefined
And another time the app crashed with:
undefined is not an object (evaluating 'n.observer')
Does anyone have an example of a working subscription setup?
I can reproduce this error now consistently on a real device by toggling the wifi on/off and unsubscribing/resubscribing.
We are seeing something very similar (perhaps the same) with v3.0.2 where subscriptions cause a crash on this line. As @wimvdb mentioned, it happens consistently on real devices when resubscribing. I've struggled to get it to happen in the simulator.
Here's our trace, note it's from dSYM mappings so s.error
=== observer.error
.
Update after bumping some dependencies and attempting to further isolate the problem, I'm seeing the same error as @wimvdb on the same line.
And again, it is very straight-forward to reproduce on a real device. Happens within a few seconds of re-launching the app (background to foreground app starts only - does not happen on fresh app starts).
@elorzafe Is this something you could help with? Looks like this whole file came along with your work in #484 with the addition of the new real-time native websockets stuff in AppSync (which is awesome btw). Thanks so much for your work on this!
I am getting this a lot too using 3.0.2
I was able to resolve the problem by updating my velocity templates to the latest version from:
"version": "2017-02-28", to "version": "2018-05-29".
After changing this the connection reconnects automatically after the device goes offline and comes back online. It does take a few minutes before it's ready to receive new messages and messages that were sent while the connection was not yet established are lost.
Wow @wimvdb thanks for sharing. I've been struggling with this one.
I actually don't have velocity templates set up for my subscription. Haven't had a need for one.
I haven't seen an example of a subscription resolver that would basically only set the version like you did... can you share yours?..
@roni-frantchi sure
request.vtl:
{ "version": "2018-05-29", "payload": {} }
response.vtl: `#if(${context.identity.sub} != ${context.arguments.ownerId}) $utils.unauthorized()
null
@wimvdb Sadly I can't say the same. We've been on 2018-05-29 from the beginning for all templates and are still unable to work around this constant crash. There are clearly client-side library issues here where native application scenarios - intermittent connections, suspended/backgrounded app processes, etc - were not considered/tested.
Thanks @wimvdb .
Using that though, I'm getting:
{"errorType":"MappingTemplate","message":"Value for field '$[operation]' not found."}
Do any of you use a failover strategy for their subscription (to handle socket timeouts for example) which tries to unsub/resub agressivelly?
If so I think it could be the issue and related to https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/515
I'm also facing this bug. I upgraded my velocity template versions to "2018-05-29", but that didn't help (note that I don't have any subscription resolvers, just Query and Mutation resolvers).
Tried with 3.0.2, 3.0.3, and 3.0.4 and am still getting the error in the screenshot above ("Undefined is not an object evaluating '_a.observer'). Downgrading to aws-appsync and aws-appsync-react to v2.0.2 fixed the issue and my app no longer routinely crashes.
I'm using Expo SDK v36 which uses React 16.9 and react-native 0.61.
also using 2018-05-29, also having this issue
Same problem for me
I use OPENID_CONNECT to authenticate and create a subscription which works fine until after a while the accessToken expires and I get a network error.
How should I configure my subscriptions to automatically refresh the token?
My configuration:
The subscription:
The subscription invocation: