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.41k stars 2.12k forks source link

Amplify DataStore creating data only locally on NextJS API Route #8792

Closed casperibo closed 2 years ago

casperibo commented 3 years ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

DataStore

Amplify Categories

api

Environment information

``` # Put output below this line System: OS: macOS 11.4 CPU: (8) arm64 Apple M1 Memory: 88.58 MB / 8.00 GB Shell: 5.8 - /bin/zsh Binaries: Node: 16.2.0 - /usr/local/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 7.13.0 - /usr/local/bin/npm Browsers: Chrome: 92.0.4515.159 Firefox: 91.0.1 Safari: 14.1.1 npmPackages: @ampproject/toolbox-optimizer: undefined () @babel/core: undefined () @tailwindcss/typography: ^0.4.1 => 0.4.1 @types/react: ^17.0.15 => 17.0.19 amphtml-validator: undefined () arg: undefined () async-retry: undefined () async-sema: undefined () autoprefixer: ^10.3.1 => 10.3.2 aws-amplify: ^4.2.2 => 4.2.4 axios: ^0.21.1 => 0.21.1 bfj: undefined () cacache: undefined () ci-info: undefined () comment-json: undefined () compression: undefined () conf: undefined () content-type: undefined () cookie: undefined () css-loader: undefined () debug: undefined () devalue: undefined () easymde: ^2.15.0 => 2.15.0 escape-string-regexp: undefined () eslint: 7.32.0 => 7.32.0 eslint-config-next: 11.0.1 => 11.0.1 file-loader: undefined () find-cache-dir: undefined () find-up: undefined () fresh: undefined () gzip-size: undefined () http-proxy: undefined () ignore-loader: undefined () is-animated: undefined () is-docker: undefined () is-wsl: undefined () json5: undefined () jsonwebtoken: undefined () loader-utils: undefined () lodash.curry: undefined () lru-cache: undefined () mini-css-extract-plugin: undefined () moment: ^2.29.1 => 2.29.1 nanoid: undefined () neo-async: undefined () next: 11.0.1 => 11.0.1 ora: undefined () postcss: ^8.3.6 => 8.3.6 (8.2.13) postcss-flexbugs-fixes: undefined () postcss-loader: undefined () postcss-preset-env: undefined () postcss-scss: undefined () react: 17.0.2 => 17.0.2 react-dom: 17.0.2 => 17.0.2 react-icons: ^4.2.0 => 4.2.0 react-markdown: ^6.0.3 => 6.0.3 react-simplemde-editor: ^5.0.1 => 5.0.1 recast: undefined () resolve-url-loader: undefined () sass-loader: undefined () schema-utils: undefined () semver: undefined () send: undefined () source-map: undefined () string-hash: undefined () strip-ansi: undefined () tailwindcss: ^2.2.7 => 2.2.7 terser: undefined () text-table: undefined () typescript: ^4.3.5 => 4.3.5 unistore: undefined () web-vitals: undefined () webpack: undefined () webpack-sources: undefined () npmGlobalPackages: @aws-amplify/cli: 5.3.0 expo-cli: 4.3.4 gatsby-cli: 3.5.0 n: 7.2.2 npm: 7.13.0 typeorm: 0.2.30 yarn: 1.22.10 ```

Describe the bug

Hi i'm using AWS Amplify with DataStore to create fullstack app and i faced a problem that doesn't go away.

I will describe my problem with a basic example.

Schema:

type Post @model {
  id: ID!
  owner: String
  title: String
  content: String!
}

If i try to save a data to the Post model in NextJS API route it will work but if i add

@auth(
    rules: [
      { allow: owner, ownerField: "owner" }
      { allow: public, operations: [read] }
    ]
  )

rule like that and try to save a data, the data will create only locally and not properly.

Here is my API route code example:


import Amplify, { AuthModeStrategyType, withSSRContext } from "aws-amplify";
import { NextApiRequest, NextApiResponse } from "next";
import { Post } from "../../../models";
import config from "../../../aws-exports";

// Amplify SSR configuration needs to be done within each API route
Amplify.configure({
  ...config,
  DataStore: {
    authModeStrategyType: AuthModeStrategyType.MULTI_AUTH,
  },
  ssr: true,
});

export default async (req: NextApiRequest, res: NextApiResponse) => {
    const { Auth, DataStore } = withSSRContext({ req });

    try {
      const user = await Auth.currentAuthenticatedUser();

      if (!user) {
        return res.status(401).json({ error: "Unauthorized request!" });
      }

      const newPost = await DataStore.save(new Post({
          title: "test",
          content: "Lorem ipsum dolor"
      }));

      return res.status(200).json(newPost);
    } catch (error) {
      console.log(error);
      return res.status(400).json(error);
    }
  };

Expected behavior

The data should be created on cloud like when i adding data without @auth rule.

Reproduction steps

Try to create data on NextJS API route you probably will facing with the same problem.

Code Snippet

// Put your code below this line.

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

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

iartemiev commented 3 years ago

Hey @casperibo, I would enable logs with Amplify.Logger.LOG_LEVEL = 'DEBUG' and then check the logs in your Next.js app to see there are any warnings or errors coming from DataStore. If there are, please share them here.

casperibo commented 3 years ago

Hi @iartemiev thank you for your response, i finally could see an error.

I think DataStore try to use API key when i try to save data.

Normally i would do AUTH_TYPE.AMAZON_COGNITO_USER_POOLS, on API but do i have to declare anything on my DataStore.save command?

I faced some error when try to debug.

[DEBUG] 20:34.280 DataStore - Mutation failed with authMode: API_KEY [DEBUG] 20:34.514 AuthClass - getting current authenticated user [DEBUG] 20:34.514 AuthClass - get current authenticated userpool user [DEBUG] 20:34.514 AuthClass - Failed to get user from user pool [DEBUG] 20:34.515 AuthClass - The user is not authenticated by the error No current user [DEBUG] 20:34.516 DataStore - Attempting sync with authMode: API_KEY

If you can look my code again, I'm getting user from withSSRContext and i can console.log current user successfully.

casperibo commented 3 years ago

I console log Auth and Datastore coming from withSSRContext({ req }) and found;

Auth._config.aws_appsync_authenticationType is "API_KEY";
DataStore.amplifyConfig.aws_appsync_authenticationType is "API_KEY";

I try to change them but still getting same "Mutation failed with authMode: API_KEY" error.

// Didn't work
Auth._config.aws_appsync_authenticationType = "COGNITO_USER_POOLS";
DataStore.amplifyConfig.aws_appsync_authenticationType = "COGNITO_USER_POOLS";
casperibo commented 3 years ago

Hi @iartemiev can you take a look this situation when you available? I'm still in same situation.

casperibo commented 3 years ago

@chrisbonifacio Hi, i saw your message in a aws-amplify issue page(link below), the problem still didn't fixed.

Should i use API in NextJS API routes or is there a way to use  DataStore for authenticated requests?

https://github.com/aws-amplify/amplify-js/issues/8454#issuecomment-862827238

iartemiev commented 2 years ago

This will be fixed in https://github.com/aws-amplify/amplify-js/pull/10088

iartemiev commented 2 years ago

We released a fix for this issue in aws-amplify@4.3.28