awslabs / aws-mobile-appsync-sdk-js

JavaScript library files for Offline, Sync, Sigv4. includes support for React Native
Apache License 2.0
920 stars 266 forks source link

Network error with offline in Chrome Extension #416

Open mattbarry opened 5 years ago

mattbarry commented 5 years ago

I'm working on a web browser extension in which I would like to use AppSync to query data from DynamoDB. To get up and running quickly, I generated the "Event App" sample project in the AppSync API console. Then I added the following code to my extension's background page:

import appSyncConfig from './aws-exports';
import AWSAppSyncClient from 'aws-appsync';
import gql from 'graphql-tag';

const client = new AWSAppSyncClient({
  url: appSyncConfig.aws_appsync_graphqlEndpoint,
  region: appSyncConfig.aws_appsync_region,
  auth: {
    type: appSyncConfig.aws_appsync_authenticationType,
    apiKey: appSyncConfig.aws_appsync_apiKey
  }
});

const query = gql`
query {
  listEvents(limit: 1000) {
    items {
      id
      name
      where
      when
      description
      comments {
        items {
          commentId
        }
      }
    }
  }
}`;

client.query({
  query
})
.then(result => console.log(result));

This code works as expected when I run it as a temporary extension in FireFox. I can see the result of my query in the console and I can see some reduxPersist entries added to local storage. It also works when I run it in the context of a web page (using a file:// URL) under both FireFox and Chrome.

However it bombs when I run it as a Chrome extension with the following Network error:

Screen Shot 2019-05-26 at 2 37 06 PM

Setting disableOffline:true fixes the query. However I lose offline support and nothing gets written to local storage.

I realize that browser extensions are probably an edge case for the JS SDK, but I'm wondering if anybody could offer some guidance in terms of debugging this issue.

NeillGiraldo commented 4 years ago

Any update on this issue?

NeillGiraldo commented 4 years ago

I managed to do a workaround for this. The problem here is that redux-offline relies on this detect network (default) script ... and in extensions, specifically in background pages this script does not work. The reason is that the callback of the window.requestAnimationFrame function is never called - Here is the explanation why.

As the AppSyncClient uses the default detectNetwork script, this issue is inherited and causes issues like this one. Good news is that redux offline allows users to provide their own implementation of the network detect, I created this pull request #499 that can fix this issue.

A custom detectNetwork function could be something like this.

const handle: Function = (callback: NetworkCallback, online: boolean): void => {
  setTimeout(() => (
    callback({ online })
  ), 0);
};

this.detectNetwork = (callback: NetworkCallback) => {
 if (typeof window !== 'undefined' && window.addEventListener) {
   window.addEventListener('online', () => (
     handle(callback, true)
   ));
   window.addEventListener('offline', () => (
     handle(callback, false)
   ));
   handle(callback, window.navigator.onLine);
 }
};

@elorzafe and @manueliglesias could you please take a look at this?