AirLabsTeam / react-native-aws-cognito-js

React Native AWS Cognito JS SDK
Other
134 stars 19 forks source link

Is using CognitoSync Possible? #2

Closed MattyK14 closed 7 years ago

MattyK14 commented 7 years ago

I was wondering if using CognitoSync was possible with this module?

jmparsons commented 7 years ago

@MattyK14 I can look into it. Right now I'm double checking everything on the storage front and Cognito Sync is on my radar as well.

jmparsons commented 7 years ago

@MattyK14 I just wrote this up, but haven't tested it. Can you try this code out?

The cognito sync has its own memory store, but it should be fine if you use it with the sync method if you're refreshing the app:

//AWS
import AWS from 'aws-sdk/dist/aws-sdk-react-native';
import 'react-native-aws-cognito-js';
import 'amazon-cognito-js';

export const appConfig = {
  region: '',
  IdentityPoolId: '',
  UserPoolId: '',
  ClientId: '',
};
//- for federated identities
appConfig.LoginId = `cognito-idp.${appConfig.region}.amazonaws.com/${appConfig.UserPoolId}`;

AWS.config.region = appConfig.region;
//- for federated identities
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
  IdentityPoolId: appConfig.IdentityPoolId,
});

export const poolData = {
  UserPoolId: appConfig.UserPoolId,
  ClientId: appConfig.ClientId,
};

export const userPool = new AWS.CognitoIdentityServiceProvider.CognitoUserPool(poolData);

export default AWS;
//App
import AWS, { userPool } from './AWS';

const myDataset = 'myDataSet';

state = {
  client: null,
}

componentDidMount() {
  userPool.storage.sync((err, result) => {
    this.setState({ client: new AWS.CognitoSyncManager() });
  });
}

putValue = (key, value) => {
  const { client } = this.state;
  client.openOrCreateDataset(myDataset, (err, dataset) => {
    if (err) return console.log(err);
    dataset.put(key, value, (dataError, record) => {
      if (dataError) return console.log(dataError);
      console.log('record', record);
    });
  });
}

syncList = () => {
  const { client } = this.state;
  client.openOrCreateDataset(myDataset, (err, dataset) => {
    if (err) return console.log(err);
    dataset.getAllRecords((dataError, records) => {
      if (dataError) return console.log(dataError);
      console.log(records);
    });
  });
}

syncStore = () => {
  const { client } = this.state;
  client.openOrCreateDataset(myDataset, (err, dataset) => {
    if (err) return console.log(err);
    dataset.synchronize({
      onSuccess: (data, newRecords) => {
        console.log('records', newRecords);
      },
      onFailure: (dataError) => {
        console.log('error', dataError);
      }
    });
  });
}
MattyK14 commented 7 years ago

@jmparsons work good man!

jmparsons commented 7 years ago

@MattyK14 Awesome great to hear!

anthonyjoeseph commented 7 years ago

For me, the above AWS.js breaks the packager on a fresh react-native project.

Added dependencies:

react-native init testProject
cd testProject
yarn add aws-sdk
yarn add react-native-aws-cognito-js
yarn add amazon-cognito-js
react-native link react-native-aws-cognito-js

Copied AWS.js as written above

Imported into index.ios.js like this:

import AWS from './AWS';

And the packager bombs with:

Bundling `index.ios.js`  99.4% (316/317), failed.
error: bundling failed: "Unable to resolve module 'aws-sdk' from '.../testProject/node_modules/amazon-cognito-js/dist/amazon-cognito.min.js': Module does not exist in the module map or in these directories:.../testProject/node_modules

(the module does exist in that directory!)

using: yarn v0.27.5, node v8.1.3, npm v5.1.0, and react-native-cli v5.1.0

jmparsons commented 7 years ago

@anthonyjoeseph leave off the "yarn add aws-sdk" it's already included in this library and points to the correct react native version, so by adding it you're pointing to the wrong one.

anthonyjoeseph commented 7 years ago

Thanks @jmparsons, that helped. I got it to work, but not satisfactorily.

In my own code, I initialized CognitoSyncManager with a parameter to make it explicitly use in-memory storage, as opposed to a web browser's LocalStorage:

new AWS.CognitoSyncManager({DataStore: AWS.CognitoSyncManager.StoreInMemory})

I also found that node_modules/amazon-cognito-js/dist/amazon-cognito.min.js requires the wrong version of aws-sdk on line 11:

module.exports = factory(require("aws-sdk"));

It worked when I changed it to:

module.exports = factory(require("aws-sdk/dist/aws-sdk-react-native"));

Since, for my project, it's not ideal to modify code in node_modules, I've submitted an issue to amazon-cognito-js and posted about it on amazon forums. I'll post when I hear back, although hopefully that the amazon team is more focused on supporting aws-sdk-react-native than resolving little amazon-cognito-js issues.

jmparsons commented 7 years ago

@anthonyjoeseph If those changes are necessary I'd recommend doing a fork, then pulling your package in via git. It's a pretty common use case where you might want to fork your entire package environment to freeze builds, then change what is necessary for a production app.

I haven't used cognito sync outside of web, so the snippet I pasted was from testing on web. I do all my testing on the web cognito, then transition it to mobile.