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.43k stars 2.13k forks source link

After added DataStore, the frontend is keep sending graphql requests for syncing data, with error responses "Unknown type AWSTimestamp" #12490

Closed nxia416 closed 1 year ago

nxia416 commented 1 year ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

DataStore

Amplify Categories

api

Environment information

``` # Put output below this line Need to install the following packages: envinfo Ok to proceed? (y) y System: OS: macOS 14.0 CPU: (8) arm64 Apple M1 Memory: 47.75 MB / 16.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node Yarn: 1.22.19 - /opt/homebrew/bin/yarn npm: 8.11.0 - /opt/homebrew/bin/npm Browsers: Chrome: 118.0.5993.117 Chrome Canary: 120.0.6099.2 Safari: 17.0 npmPackages: @ampproject/toolbox-optimizer: undefined () @babel/core: undefined () @babel/runtime: 7.22.5 @edge-runtime/cookies: 4.0.2 @edge-runtime/ponyfill: 2.4.1 @edge-runtime/primitives: 4.0.2 @hapi/accept: undefined () @mswjs/interceptors: undefined () @napi-rs/triples: undefined () @next/font: undefined () @next/react-dev-overlay: undefined () @opentelemetry/api: undefined () @segment/ajv-human-errors: undefined () @vercel/nft: undefined () @vercel/og: 0.5.15 acorn: undefined () amphtml-validator: undefined () anser: undefined () arg: undefined () assert: undefined () async-retry: undefined () async-sema: undefined () aws-amplify: ^5.3.11 => 5.3.11 babel-packages: undefined () browserify-zlib: undefined () browserslist: undefined () buffer: undefined () bytes: undefined () ci-info: undefined () cli-select: undefined () client-only: 0.0.1 comment-json: undefined () compression: undefined () conf: undefined () constants-browserify: undefined () content-disposition: undefined () content-type: undefined () cookie: undefined () cross-spawn: undefined () crypto-browserify: undefined () css.escape: undefined () data-uri-to-buffer: undefined () debug: undefined () devalue: undefined () domain-browser: undefined () edge-runtime: undefined () eslint: ^8 => 8.52.0 eslint-config-next: 14.0.1 => 14.0.1 events: undefined () find-cache-dir: undefined () find-up: undefined () fresh: undefined () get-orientation: undefined () glob: undefined () gzip-size: undefined () http-proxy: undefined () http-proxy-agent: undefined () https-browserify: undefined () https-proxy-agent: undefined () icss-utils: undefined () ignore-loader: undefined () image-size: undefined () is-animated: undefined () is-docker: undefined () is-wsl: undefined () jest-worker: undefined () json5: undefined () jsonwebtoken: undefined () loader-runner: undefined () loader-utils: undefined () lodash.curry: undefined () lru-cache: undefined () micromatch: undefined () mini-css-extract-plugin: undefined () nanoid: undefined () native-url: undefined () neo-async: undefined () next: 14.0.1 => 14.0.1 node-fetch: undefined () node-html-parser: undefined () ora: undefined () os-browserify: undefined () p-limit: undefined () path-browserify: undefined () platform: undefined () postcss-flexbugs-fixes: undefined () postcss-modules-extract-imports: undefined () postcss-modules-local-by-default: undefined () postcss-modules-scope: undefined () postcss-modules-values: undefined () postcss-preset-env: undefined () postcss-safe-parser: undefined () postcss-scss: undefined () postcss-value-parser: undefined () process: undefined () punycode: undefined () querystring-es3: undefined () raw-body: undefined () react: ^18 => 18.2.0 react-builtin: undefined () react-dom: ^18 => 18.2.0 react-dom-builtin: undefined () react-dom-experimental-builtin: undefined () react-experimental-builtin: undefined () react-is: 18.2.0 react-refresh: 0.12.0 react-server-dom-turbopack-builtin: undefined () react-server-dom-turbopack-experimental-builtin: undefined () react-server-dom-webpack-builtin: undefined () react-server-dom-webpack-experimental-builtin: undefined () regenerator-runtime: 0.13.4 sass-loader: undefined () scheduler-builtin: undefined () scheduler-experimental-builtin: undefined () schema-utils: undefined () semver: undefined () send: undefined () server-only: 0.0.1 setimmediate: undefined () shell-quote: undefined () source-map: undefined () stacktrace-parser: undefined () stream-browserify: undefined () stream-http: undefined () string-hash: undefined () string_decoder: undefined () strip-ansi: undefined () superstruct: undefined () tar: undefined () terser: undefined () text-table: undefined () timers-browserify: undefined () tty-browserify: undefined () ua-parser-js: undefined () unistore: undefined () util: undefined () vm-browserify: undefined () watchpack: undefined () web-vitals: undefined () webpack: undefined () webpack-sources: undefined () ws: undefined () zod: undefined () npmGlobalPackages: @aws-amplify/cli: 12.7.0 npm: 8.11.0 yarn: 1.22.19 ```

Describe the bug

After added GraphQL API and Auth, I am trying to use DataStore for a frontend cache. However, I notice that DataStore keeps sending graphql requests:

The reaponse suggests the requests are all failed:

image

Expected behavior

fix the sync results or turn off the data syncing.

Reproduction steps

  1. install graphql api, and authentication
  2. create the api with the given schema
  3. run amplify codegen models to create models
  4. add DataStore.query to the frontend query Blogs
  5. from chrome you can see the graphql error response:
{
    "data": null,
    "errors": [
        {
            "path": null,
            "locations": [
                {
                    "line": 1,
                    "column": 61,
                    "sourceName": null
                }
            ],
            "message": "Validation error of type UnknownType: Unknown type AWSTimestamp"
        },
        {
            "path": null,
            "locations": [
                {
                    "line": 2,
                    "column": 3,
                    "sourceName": null
                }
            ],
            "message": "Validation error of type FieldUndefined: Field 'syncBlogs' in type 'Query' is undefined @ 'syncBlogs'"
        }
    ]
}

Code Snippet

GraphQL schema is from the official example:


type Blog
  @model
  @auth(
    rules: [
      { allow: groups, groups: ["Admins"] }
      { allow: public, operations: [read] }
    ]
  ) {
  id: ID!
  name: String!
  posts: [Post] @hasMany
}

type Post
  @model
  @auth(
    rules: [
      { allow: groups, groups: ["Admins"] }
      { allow: public, operations: [read] }
    ]
  ) {
  id: ID!
  title: String!
  blog: Blog @belongsTo
  comments: [Comment] @hasMany
}

type Comment
  @model
  @auth(
    rules: [
      { allow: groups, groups: ["Admins"], operations: [delete] }
      { allow: owner }
      { allow: public, operations: [read] }
    ]
  ) {
  id: ID!
  content: String
  post: Post @belongsTo
}

Log output

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

aws-exports.js

/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.

const awsmobile = {
    "aws_project_region": "ap-southeast-1",
    "aws_cognito_identity_pool_id": "ap-southeast-1:0000000000-3070-416d-a351-2980801cf2ea",
    "aws_cognito_region": "ap-southeast-1",
    "aws_user_pools_id": "ap-southeast-1_adfasdfasfd",
    "aws_user_pools_web_client_id": "asdfadfadfasdfasdfadsf",
    "oauth": {},
    "aws_cognito_username_attributes": [
        "EMAIL"
    ],
    "aws_cognito_social_providers": [],
    "aws_cognito_signup_attributes": [
        "EMAIL"
    ],
    "aws_cognito_mfa_configuration": "OFF",
    "aws_cognito_mfa_types": [
        "SMS"
    ],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": []
    },
    "aws_cognito_verification_mechanisms": [
        "EMAIL"
    ],
    "aws_appsync_graphqlEndpoint": "https://asdfasdfasdfasdfasdf.appsync-api.ap-southeast-1.amazonaws.com/graphql",
    "aws_appsync_region": "ap-southeast-1",
    "aws_appsync_authenticationType": "API_KEY",
    "aws_appsync_apiKey": "da2-asdfasdfasdfasdfasdfasdf"
};

export default awsmobile;

Manual configuration

No response

Additional configuration

Here is my cache method:

import {
  Amplify,
  API,
  graphqlOperation,
  AuthModeStrategyType,
} from "aws-amplify";
import { DataStore, Predicates } from "aws-amplify";

import { Blog, Post, Comment } from "src/models";

import awsconfig from "src/aws-exports";
Amplify.configure({
  ...awsconfig,
  DataStore: {
    authModeStrategyType: AuthModeStrategyType.MULTI_AUTH,
  },
});

import { listBlogs } from "src/graphql/queries";

export async function getBlogs() {
  console.log("---- before call DataStore");
  const cachedBlogs = await DataStore.query(Blog);
  console.log("---- endend call DataStore");
  console.log("cachedBlogs: ", cachedBlogs);

  const blogs = await API.graphql(graphqlOperation(listBlogs));
  return blogs;
}

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

nxia416 commented 1 year ago

Another more general question is, can I use DataStore to pre-fetch data for frontend data caching? It seems when saving the items queried from API to DataStore, the id of the item will be changed: that means I can't save the API query results into DataStore? So I guess, DataStore is only for local-first scenarios, not for date pre-fetching?

chrisbonifacio commented 1 year ago

Hi @nxia416 👋 thanks for raising this issue. It seems that a field and query is missing from your schema. If you run amplify status do you see that the API resource is in Update status? Perhaps you have some changes that need to be deployed using amplify push

Also, be sure that Conflict detection is enabled by running amplify update api > GraphQL > enable conflict detection

Otherwise, try running amplify codegen models to regenerate the local model schema for DataStore.

Also, you are correct that DataStore is not intended to be used as a cache. It is for local first scenarios.

Unless you have a specific use case for offline capabilities, we recommend using the API category for the best balance of performance and reliability when interfacing with your Amplify GraphQL API.

nxia416 commented 1 year ago

@chrisbonifacio thanks for the response! I will try "enable conflict detection", I guess that is the missing part.

My main purpose is for javascript frontend caching. I figured out I could use import { Cache } from "aws-amplify" for that. So my problem is sovled. Thanks again.