aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

Amplify configuration issue inside micro front-end environnement #12986

Closed Keling-Molaris closed 1 month ago

Keling-Molaris commented 7 months ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

Authentication, GraphQL API, Storage

Amplify Version

v6

Amplify Categories

auth, storage, api

Backend

Amplify CLI

Environment information

``` System: OS: macOS 14.2.1 CPU: (12) arm64 Apple M2 Max Memory: 111.63 MB / 32.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 20.1.0 - /opt/homebrew/bin/node Yarn: 1.22.19 - /opt/homebrew/bin/yarn npm: 9.6.4 - /opt/homebrew/bin/npm Watchman: 2023.05.15.00 - /opt/homebrew/bin/watchman Browsers: Chrome: 121.0.6167.160 Safari: 17.2.1 npmPackages: @aws-amplify/ui-react: ^6.1.3 => 6.1.3 @aws-amplify/ui-react-internal: undefined () @babel/core: ^7.12.3 => 7.22.5 @babel/plugin-transform-runtime: ^7.23.7 => 7.23.9 @babel/preset-env: ^7.12.1 => 7.22.5 @babel/preset-react: ^7.12.1 => 7.22.5 @babel/preset-typescript: ^7.23.3 => 7.23.3 @emotion/react: ^11.11.1 => 11.11.3 @emotion/styled: ^11.11.0 => 11.11.0 @mui/icons-material: ^5.15.0 => 5.15.9 @mui/material: ^5.15.0 => 5.15.9 @nextui-org/react: ^2.2.9 => 2.2.9 aws-amplify: ^6.0.15 => 6.0.15 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () babel-loader: ^8.1.0 => 8.3.0 clean-webpack-plugin: ^3.0.0 => 3.0.0 css-loader: ^5.2.7 => 5.2.7 html-webpack-plugin: ^4.5.0 => 4.5.2 postcss: ^8.4.32 => 8.4.35 postcss-loader: ^7.3.3 => 7.3.4 postcss-preset-env: ^9.3.0 => 9.3.0 react: ^18.2.0 => 18.2.0 react-dom: ^18.2.0 => 18.2.0 react-router-dom: ^5.2.0 => 5.3.4 style-loader: ^2.0.0 => 2.0.0 tailwindcss: ^3.4.0 => 3.4.1 webpack: ^5.90.0 => 5.90.1 webpack-cli: ^4.1.0 => 4.10.0 webpack-dev-server: ^3.11.0 => 3.11.3 webpack-merge: ^5.2.0 => 5.9.0 npmGlobalPackages: @angular/cli: 17.0.7 @aws-amplify/cli: 12.2.0 amplify-graphql-seed-plugin: 0.1.13 create-expo-app: 2.0.3 expo-cli: 6.3.10 npm: 9.6.4 react-devtools: 4.27.8 ```

Describe the bug

We try to call GraphQL API in two different micro front-end app, each one has an amplify backend, and we got issues like: [Warning] [WARN] 21:04.237 GraphQLAPI resolveConfig - The API configuration is missing. This is likely due to Amplify.configure() not being called prior to generateClient(). Error: No credentials image

If we active authenticator, we have : Auth UserPool not configured. image

In our code, we called Amplify.configure(config) in App.ts.

Expected behavior

Authentication works, and GraphQL API return data correctly.

Reproduction steps

  1. Create two react applications
  2. Assemble as micro front-end, one as main application, seconde one as an imported component. We use webpack for assembling the two app.
  3. Create two amplify app backend link main application and seconde application to each.
  4. Add API, Auth etc. for the two amplify backend
  5. Pull amplify into each project (main, second)
  6. Amplify update codegen to get API helper
  7. Call Amplify.configure(config) in both App.ts.

in main application:

import { Amplify } from 'aws-amplify';
import config from './amplifyconfiguration.json';
import { generateClient } from 'aws-amplify/api';
import { listUsers } from './graphql/queries.ts';
import { User } from "./API";

Amplify.configure(config);
const client = generateClient();

in second application:

import { Amplify } from 'aws-amplify';
import config from './amplifyconfiguration.json';
import { generateClient } from 'aws-amplify/api';
import { listOrders } from './graphql/queries.ts';
import { Order } from "./API";

Amplify.configure(config);
const client = generateClient();
  1. Call GraphQL API in main Application App.ts:

    useEffect(() => {
    const fetchUsers = async () => {
      try {
        const users = await client.graphql({ query: listUsers });
        setUsers(users);
      } catch (error) {
        console.error('Error fetching data:', error);
      }
    };
    fetchUsers();
    }, []);
  2. Call GraphQL API in seconde Application App.ts:

      useEffect(() => {
      const fetchOrders = async () => {
        try {
          const orders = await client.graphql({ query: listOrders });
    
          setOrders(orders);
        } catch (error) {
          console.error('Error fetching data:', error);
        }
      };
    
      fetchOrders();
    
    }, []);

Code Snippet

// Put your code below this line.

Log output

``` index.js:53 [WDS] Live Reloading enabled. react-dom.development.js:29835 Download the React DevTools for a better development experience: https://reactjs.org/link/react-devtools App.tsx:72 [] App.tsx:72 [] ConsoleLogger.mjs:80 [WARN] 17:59.268 GraphQLAPI resolveConfig - The API configuration is missing. This is likely due to Amplify.configure() not being called prior to generateClient(). _log @ ConsoleLogger.mjs:80 ConsoleLogger.mjs:80 [WARN] 17:59.268 GraphQLAPI resolveConfig - The API configuration is missing. This is likely due to Amplify.configure() not being called prior to generateClient(). _log @ ConsoleLogger.mjs:80 ConsoleLogger.mjs:80 [WARN] 17:59.268 GraphQLAPI resolveConfig - The API configuration is missing. This is likely due to Amplify.configure() not being called prior to generateClient(). _log @ ConsoleLogger.mjs:80 ConsoleLogger.mjs:80 [WARN] 17:59.268 GraphQLAPI resolveConfig - The API configuration is missing. This is likely due to Amplify.configure() not being called prior to generateClient(). App.tsx:59 Error fetching data: Error: No credentials at GraphQLAPIClass._headerBasedAuth (InternalGraphQLAPI.mjs:73:27) at async GraphQLAPIClass._graphql (InternalGraphQLAPI.mjs:186:18) _callee$ @ App.tsx:59 ```

aws-exports.js

const awsmobile = {
    "aws_project_region": "us-east-1",
    "aws_appsync_graphqlEndpoint": "https:/******-appsync-api.us-east-1.amazonaws.com/graphql",
    "aws_appsync_region": "us-east-1",
    "aws_appsync_authenticationType": "API_KEY",
    "aws_appsync_apiKey": "da2-*******",
    "aws_cognito_identity_pool_id": "us-east-********",
    "aws_cognito_region": "us-east-1",
    "aws_user_pools_id": "us-east-1_******",
    "aws_user_pools_web_client_id": "*********",
    "oauth": {},
    "aws_cognito_username_attributes": [
        "EMAIL"
    ],
    "aws_cognito_social_providers": [],
    "aws_cognito_signup_attributes": [],
    "aws_cognito_mfa_configuration": "OFF",
    "aws_cognito_mfa_types": [
        "SMS"
    ],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": [
            "REQUIRES_LOWERCASE",
            "REQUIRES_NUMBERS",
            "REQUIRES_SYMBOLS",
            "REQUIRES_UPPERCASE"
        ]
    },
    "aws_cognito_verification_mechanisms": [
        "EMAIL"
    ],
    "aws_user_files_s3_bucket": "mfe-test-storage-*********",
    "aws_user_files_s3_bucket_region": "us-east-1"
};

export default awsmobile;

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

cwomack commented 7 months ago

Hello, @Keling-Molaris and sorry to hear that you're running into this. I believe this could be related to a known issue where there was a race condition potentially with Amplify.configure() calls when using the GraphQL API library. A fix was released in v6.0.16 just last week after you opened this issue.

Can you see if upgrading to the latest version resolves the errors you're seeing? If not, we'll dig deeper to figure out what is going on. Thanks!

Keling-Molaris commented 7 months ago

Hi @cwomack , Thanks for your reply. Just try to use v6.0.16 unfortunately, the issue still persist. And in the second app, I aways have the first app's config.

DeveloperDS-123 commented 7 months ago

Hello

I am also getting the same error.

I can successfully run the app locally, and the GraphQL API works fine (local). However, after deploying it to Amplify for production, the GraphQL API seems to encounter issues.

downloadpp

This is my Packages

"dependencies": { "@aws-amplify/auth": "^6.0.16", "@aws-amplify/datastore": "^5.0.16", "@aws-amplify/ui-react": "^6.1.3", "@emotion/cache": "^11.9.3", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.8.4", "@mui/lab": "^5.0.0-alpha.88", "@mui/material": "^5.14.20", "@mui/system": "^5.8.6", "@mui/utils": "^5.8.6", "@reduxjs/toolkit": "^2.0.1", "@tabler/icons": "^1.72.0", "apexcharts": "^3.35.3", "aws-amplify": "^6.0.16", "axios": "^1.6.2", "formik": "^2.2.9", "framer-motion": "^6.3.16", "material-ui-popup-state": "^4.0.1", "prop-types": "^15.8.1", "react": "^18.2.0", "react-apexcharts": "^1.4.0", "react-card-flip": "^1.2.2", "react-device-detect": "^2.2.2", "react-dom": "^18.2.0", "react-phone-input-2": "^2.15.1", "react-redux": "^8.0.2", "react-responsive-carousel": "^3.2.23", "react-router": "6.4.0", "react-router-dom": "6.4.0", "react-scripts": "^5.0.1", "react-slick": "^0.29.0", "react-toastify": "^9.1.3", "redux": "^4.2.0", "redux-thunk": "^2.4.2", "uuid": "^9.0.1", "yup": "^0.32.11" }

This is the code I did in src/app.js

amplifyapp
cwomack commented 7 months ago

@Keling-Molaris, thanks for reopening if it's still occurring. Are you also experiencing it only in prod versions/deployed apps but not locally (similar to what @DeveloperDS-123 reported above)?

We'll investigate this further and I'll place the bug label on this issue for now.

Keling-Molaris commented 7 months ago

Hi @cwomack , it's still occurring, for me the issue appears to local environment and aws hosted environment.

I gonna try some older versions of amplify lib, if there is one works.

Thank you very much!

DeveloperDS-123 commented 7 months ago

Hi @cwomack

Thanks for your reply

Still, I am facing the same issue in deployed/production only not in local.

also i am using amplify auth for login and sigup

editedaws

This is my amplifyconfiguration.json

DeveloperDS-123 commented 6 months ago

Hi @cwomack

The above error still occurring in amplify react app hosted environment not in local

Thank you very much!

satoc0629 commented 6 months ago

It doesn't work, so downgrading to "@aws-amplify/datastore": "5.0.0", seems to work fine. Also, this problem did not occur on Windows, Mac, but on Ubuntu. I hope this will be of some help.

AakashKB commented 6 months ago

^ Occuring on Mac for me currently

AakashKB commented 6 months ago

Looks like for me it was caused by the following setup

Amplify.configure(amplifyconfig);
//Uncommenting this code causes issue
// const existingConfig = Amplify.getConfig();
// Amplify.configure({
//     ...existingConfig,
//     API: {
//         REST: {
//             [amplifyconfig.custom.apiName]: {
//                 endpoint: amplifyconfig.custom.apiEndpoint,
//                 region: amplifyconfig.custom.apiRegion,
//             },
//         },
//     },
// });
imers commented 5 months ago

Looks like for me it was caused by the following setup

Amplify.configure(amplifyconfig);
//Uncommenting this code causes issue
// const existingConfig = Amplify.getConfig();
// Amplify.configure({
//     ...existingConfig,
//     API: {
//         REST: {
//             [amplifyconfig.custom.apiName]: {
//                 endpoint: amplifyconfig.custom.apiEndpoint,
//                 region: amplifyconfig.custom.apiRegion,
//             },
//         },
//     },
// });

I got the same error after adding the customized REST api.

My packages: "aws-amplify": "^6.0.23" "@aws-amplify/backend": "^0.13.0-beta.11", "@aws-amplify/backend-cli": "^0.12.0-beta.13",

matiassotose commented 5 months ago

Looks like for me it was caused by the following setup

Amplify.configure(amplifyconfig);
//Uncommenting this code causes issue
// const existingConfig = Amplify.getConfig();
// Amplify.configure({
//     ...existingConfig,
//     API: {
//         REST: {
//             [amplifyconfig.custom.apiName]: {
//                 endpoint: amplifyconfig.custom.apiEndpoint,
//                 region: amplifyconfig.custom.apiRegion,
//             },
//         },
//     },
// });

I had the same issue, solved it with the following code snippet.

const existingConfig = Amplify.getConfig();
// Check if there is an existing API configuration
if (!existingConfig.API) {
  Amplify.configure({
    ...existingConfig,
    API: {
      REST: {
        [config.custom.apiName]: {
          endpoint: config.custom.apiEndpoint,
          region: config.custom.apiRegion,
        },
      },
    },
  });
} else {
  // Merge the existing API configuration with the new one
  Amplify.configure({
    ...existingConfig,
    API: {
      ...existingConfig.API,
      REST: {
        ...existingConfig.API.REST,
        [config.custom.apiName]: {
          endpoint: config.custom.apiEndpoint,
          region: config.custom.apiRegion,
        },
      },
    },
  });
}
thomasdavidwang commented 4 months ago

Would it be possible to update the documentation to match the updated configure call? This seems to be a common configuration for Amplify, and the documentation doesn't note this issue. (ex: https://docs.amplify.aws/nextjs/build-a-backend/add-aws-services/rest-api/set-up-rest-api/)

hangoocn commented 3 months ago

@matiassotose Thanks your solution solved my issue, the issue happens on a single-page react app (not in a micro-frontend context) with custom rest api config missing ...existingConfig.API, I think it can also be simplified a bit like this:

Amplify.configure(outputs);
const existingConfig = Amplify.getConfig();
Amplify.configure({
  ...existingConfig,
  API: {
    ...existingConfig.API, // fix by this line
    REST: outputs.custom.API,
  },
});

I also folloed this doc as mentioend by @thomasdavidwang, so I also reported it as a bug in the doc repo

HuiSF commented 3 months ago

Hi all, I spent some time to play with the micro frontend environment, and noticed that when there are two instances of Amplify category packages (scoped with @aws-amplify/) I can reproduce this issue. To resolve this issue I needed to update the shared configuration of the ModuleFederationPlugin in my webpack.config.js

// the dependencies of your project
const deps = require("./package.json").dependencies;

// the dependencies of the aws-amplify package
const amplifyDeps = require("./node_modules/aws-amplify/package.json").dependencies;

...

new ModuleFederationPlugin({
    name: "mainapp",
    filename: "remoteEntry.js",
    remotes: {
        remoteComponent: "remoteComponent@http://localhost:9001/remoteEntry.js",
    },
    exposes: {},
    shared: {
        ...deps,
        ...amplifyDeps, // ensure the Amplify category packages are shared to avoid multiple instances
        react: {
            singleton: true,
            requiredVersion: deps.react
        },
        "react-dom": {
            singleton: true,
            requiredVersion: deps["react-dom"]
        }
    }
}),

This is due to that "by default webpack will only share the root level of a library" according to the webpack documentation.

If you are using a similar set up, could you give it a try see if it resolve the issue you encountered?

moellr commented 2 months ago

Hi all, I spent some time to play with the micro frontend environment, and noticed that when there are two instances of Amplify category packages (scoped with @aws-amplify/) I can reproduce this issue. To resolve this issue I needed to update the shared configuration of the ModuleFederationPlugin in my webpack.config.js [...] If you are using a similar set up, could you give it a try see if it resolve the issue you encountered?

Confirmed, your provided solution solved my issue with webpack remote modules in a Amplify v6 project. After adding the amplifyDeps as described above, the remote modules are now able to pick up the existing credentials via Amplify.configure(...) and I can successfully call Amplify API resources from there.

(Little side hint for others that face a similar issue: You also need to make sure the npm package versions for the Amplify packages are identical across main and remote applications in the in package-lock.json files. I only had minor different versions of a few packages, but that already led to credentials not being picked up.)

Thx for your support

cwomack commented 1 month ago

Thank you for the confirmation, @moellr. We'll go ahead and close this issue out on the amplify-js repo then since we are tracking the docs update in amplify-docs issue 7776. If there's further questions or blockers from anyone following this, please feel free to comment back.