aws-amplify / amplify-flutter

A declarative library with an easy-to-use interface for building Flutter applications on AWS.
https://docs.amplify.aws
Apache License 2.0
1.31k stars 242 forks source link

Max number of 100 subscriptions reached only for IOS , Android works fine. #5383

Closed jamontesg closed 2 weeks ago

jamontesg commented 2 weeks ago

Description

I have an application con 18 tables , When you logout and login, you get the following error---->

flutter: ERROR | WebSocketBloc - fb75ea94-3f65-45d9-b762-0e4fed1ae8aa | Shutting down with exception: NetworkException { "message": "Exception from WebSocketService.", "underlyingException": "type '_Map<String, dynamic>' is not a subtype of type 'List?' in type cast" }

Categories

Steps to Reproduce

configure DynamoDB/ API /. AUTH with cognito group access. do a login do a logout do a login

Screenshots

No response

Platforms

Flutter Version

3.24.1

Amplify Flutter Version

2.4.0

Deployment Method

Amplify Gen 2

Schema

# This "input" configures a global authorization rule to enable public access to
# all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules

type Tenant @model @auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative","Guest"], operations: [read]  }
  ]) {
  id: ID! @primaryKey  
  name: String!
  description: String
  locations: [Location]! 
  cLots: [CLot] 
  images: [S3Object]
  country: Country!
  license: LicenseType!

}

type Location {
  id: ID!  
  name: String!
  description: String
  owner: String
  phoneOwner: String
  phoneLocation: String
  images: [S3Object]
  latitude: Float
  longitude: Float
  date: AWSDateTime!
  update: AWSDateTime!
  production:[Production]
  groups: [Group]
  pcels: [Pcel]
  videoStream: [VideoStream]
  geometries: [AWSJSON]    
}

type Group {
  id: ID!  
  name: String!
  description: String
  date: AWSDateTime!
  update: AWSDateTime!
}

type Pcel {
  id: ID!  
  name: String!
  description: String
  date: AWSDateTime!
  latitude: Float
  longitude: Float
  geometries: [AWSJSON]
}

type CLot {
  id: ID!  
  name: String!
  description: String
  date: AWSDateTime!
}

type Food @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {
  tenantId: ID! @primaryKey(sortKeyFields: ["id"])  
  locationId: ID! @index(sortKeyFields: ["ck"])
  location: String!
  ck: String!
  ckt: String

  id: ID! 
  name: String!
  type: InventoryProductType!
  transaction : TransactionType!
    expirationDate: AWSDate
    batchNumber: String
    certification: String
    quantity: Int!
  balance: Int
  description: String
  images: [S3Object]
  date: AWSDateTime!
  user: String!
}

type Medicine @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {
  tenantId: ID! @primaryKey(sortKeyFields: ["id"])
  locationId: ID!  @index(sortKeyFields: ["ck"])
  location: String! 
  ck: String!
  ckt: String

  id: ID!  
  name: String!
  type: InventoryProductType!
  transaction : TransactionType!
    expirationDate: AWSDate
    batchNumber: String
    certification: String
    quantity: Int!
  balance: Int
  description: String
  images: [S3Object]
  date: AWSDateTime!
  user: String!
}

type Ptry @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {

  tenantId: ID! @primaryKey(sortKeyFields: ["id"])  # customized foreign key for parent primary key

  id: ID! 
  locationId: ID! @index(sortKeyFields: ["ck"])
  location: String!  
  ck: String!
  ckt: String

  name: String!
    date: AWSDateTime!
    rotationNumber: Int
    daysRest: Int
    quantity: Int
  description: String
  images: [S3Object]

}

type Applikation @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {

  tenantId: ID! @primaryKey(sortKeyFields: ["id"])  # customized foreign key for parent primary key

  id: ID! 
  locationId: ID! @index(sortKeyFields: ["ck"])
  location: String!  
  ck: String!
  ckt: String

  pcelsId: [String]

  name: String!
    date: AWSDateTime!
    rotationNumber: Int
    daysRest: Int
    quantity: Int
  description: String
  images: [S3Object]

}

type Pst @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {

  tenantId: ID! @primaryKey(sortKeyFields: ["id"])  # customized foreign key for parent primary key

  id: ID! 
  locationId: ID! @index(sortKeyFields: ["ck"])
  location: String!  
  ck: String!
  ckt: String

  pcelsId: [String]

  name: String!
    date: AWSDateTime!
    rotationNumber: Int
    daysRest: Int
    quantity: Int
  description: String
  images: [S3Object]

}

type Factory @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {

  tenantId: ID! @primaryKey(sortKeyFields: ["id"])  # customized foreign key for parent primary key

  id: ID! 
  locationId: ID! @index(sortKeyFields: ["ck"])
  location: String!  
  ck: String!
  ckt: String

  types: [ProductType]!
  slots: [Slot]!
    date: AWSDateTime!
    rotationNumber: Int
    daysRest: Int
    quantity: Int
  description: String
  production: [Production]!
  images: [S3Object]

}

type Innation @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {
  tenantId: ID! @primaryKey(sortKeyFields: ["id"])
  locationId: ID!  @index(sortKeyFields: ["ck"])
  location: String! 
  ck: String!
  ckt: String

  id: ID!  
  itemId: String!
  aid: String
  altaid: String
  alias: String

    donId: String!
  doname: String
  ve: String
  description: String
  images: [S3Object]
  date: AWSDateTime!
  user: String!
}

type Pation @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {
  tenantId: ID! @primaryKey(sortKeyFields: ["id"])
  locationId: ID!  @index(sortKeyFields: ["ck"])
  location: String! 
  ck: String!
  ckt: String

  id: ID!  
  itemId: String!
  aid: String
  altaid: String
  alias: String

  ve: String
  description: String
  images: [S3Object]
  date: AWSDateTime!
  user: String!
}

type Mits @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {
  tenantId: ID! @primaryKey(sortKeyFields: ["id"])
  locationId: ID!  @index(sortKeyFields: ["ck"])
  location: String! 
  ck: String!
  ckt: String

  id: ID!  
  itemId: String!
  aid: String
  altaid: String
  alias: String

  ve: String
  type: MType!
  lf: Boolean @default(value: "false")
  rf: Boolean @default(value: "false")
  lr: Boolean @default(value: "false")
  rr: Boolean @default(value: "false")
  description: String
  images: [S3Object]
  date: AWSDateTime!
  user: String!
}

type Medi @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {
  tenantId: ID! @primaryKey(sortKeyFields: ["id"])
  locationId: ID!  @index(sortKeyFields: ["ck"])
  location: String! 
  ck: String!
  ckt: String

  id: ID!  
  itemId: String!
  aid: String
  altaid: String
  alias: String

  name: String!

    expirationDate: AWSDate
    batchNumber: String
    certification: String
    quantity: Int!
  withdrawal: Int
  route: RouteType!
  ve: String
  description: String
  images: [S3Object]
  date: AWSDateTime!
  user: String!
}

type User @model @auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative","Guest"], operations: [read,delete]  }
  ]) {
  id: ID! @primaryKey (sortKeyFields: ["tenantId"])
  tenantId: ID! 
  locations: [Location]
  name: String!
  surname: String
  email: String!
  image: String
  status: String!
  profile: Profile!
  date: AWSDateTime!
}

type Item @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Api","Operative"], operations: [create, update, read, delete]  }
  { allow: groups, groups: ["Guest"], operations: [read]  }
  ])
 {
  tenantId: ID! @primaryKey(sortKeyFields: ["id"])  # customized foreign key for parent primary key
  #tenantId: ID! @primaryKey(sortKeyFields: ["id"])

  locationId: ID! @index(sortKeyFields: ["ck"])
  location: String!
  #location: String! @index(sortKeyFields: ["ck"])  

  id: ID!  
  group: String
  groupId: String
  pcel: String
  pcelId: String
  cLot: String
  ck: String!
  ckt: String

  aid: String
  altaid: String
  alias: String
  name: String
  description: String
  birth: AWSDate
  admissionDate: AWSDateTime!

  lastOwner: String
  cost: Float

  calg: AWSDate
  wed: AWSDate
  mat: AWSDate
  deh: AWSDate
  sie: String
  dem: String

  retag: String
  letag: String
  eid: String
  documents: [S3Object]
  events: [Event]
  images: [S3Object]
  measures: [Measure]
  production: [Production]
  weights: [Weight]

  type: AnType!
  gen: Gender!
  bree: String
  color: String
  status: ItemStatus!

  pur: Float
  dale: Float

}

type Logs @model @auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update, read]  }
  { allow: groups, groups: ["Api","Operative","Guest"], operations: [create, read]  }
  ]) {
  tenantId: ID!  @primaryKey(sortKeyFields: ["date"]) 
  id: ID!
  name: String!
  user: String!
  transaction: String!
  data: String!
  result: String!
  date: AWSDateTime!
}

type S3Object {
  name: String
  date: AWSDateTime!
  bucket: String!
  region: String!
  key: String
  localPath: String
  ownerId: String
  ownerName: String
  status: ImageStatus!
}

type Event {
  description: String!
  date: AWSDateTime!
  type: EvType!
  images: [S3Object]
  latitude:  Float
  longitude:  Float
  ownerId: String
  ownerName: String
}

type Weight {
  date: AWSDateTime!
  value : Float!
  type: WeightType!
  image: S3Object
  latitude:  Float
  longitude:  Float
  ownerId: String
  ownerName: String
}

type Measure {
  description: String
  date: AWSDateTime!
  wHeight: Float, 
  bLength: Float, 
  herth: Float,
}

type Production {
  date: AWSDateTime!
  value : Float!
  type: ProductType!
  slots: Slot
  image: S3Object
  latitude:  Float
  longitude:  Float
  ownerId: String
  ownerName: String
}

type BreeC  @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update,read]  }
  { allow: groups, groups: ["Api","Operative","Guest"], operations: [read]  }
  ]) {
  country: String! @primaryKey(sortKeyFields: ["language","breed"]) 
  language: String! 
  breed: String!
  description: String
  image: String
}

type BreeH @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update,read]  }
  { allow: groups, groups: ["Api","Operative","Guest"], operations: [read]  }
  ]) {
  country: String! @primaryKey(sortKeyFields: ["language","breed"]) 
  language: String! 
  breed: String!
  description: String
  image: String
}

type BreeD @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update,read]  }
  { allow: groups, groups: ["Api","Operative","Guest"], operations: [read]  }
  ]) {
  country: String! @primaryKey(sortKeyFields: ["language","breed"]) 
  language: String! 
  breed: String!
  description: String
  image: String
}

type BreeB @model 
@auth(rules: [
  { allow: groups, groups: ["Admin","AdminTi","Support","Manager"], operations: [create, update,read]  }
  { allow: groups, groups: ["Api","Operative","Guest"], operations: [read]  }
  ]) {
  country: String! @primaryKey(sortKeyFields: ["language","breed"]) 
  language: String! 
  breed: String!
  description: String
  image: String
}

type InventoryProductType {
  id: ID!
  metadata: String!
  name: String!
  categoryId:   ID!
  brandId:  String
}

type VideoStream {
  id: ID!  
  name: String!
  user: String  
  password: String
  ip: String
  port: Int
  url: String
  protocol: String
  channel: String
  type: VideoManufacturersType!
  geometries: [AWSJSON]  

}

enum AnType {
  c1
  c2
  c3
  c4
  c5
  C6
}

enum EvType {
  evt1
  evt2
  evt3
  evt4
  evt5
  evt6
  other
}

enum WeightType {
  wt1
  wt2
  wt3
  wt4
  wt5
  wt6
  other
}

enum Gender {
  gd1
  gd2
  other
}

enum Country {
  ct1
  ct2
  ct3
  ct4
  other
}

enum ItemStatus {
  sold
  normal
  lost
  deleted
}

enum ProductType {
  pd1
  pd2
  pd3
}
enum Slot {
  morning
  afternoon
  evening
}

enum TransactionType {
  entry
  exit
}

enum ImageStatus {
  ok
  waiting
  failed
}

enum Profile {
  Admin
  Adminti
  Support
  Manager
  Api
  Operative
  Guest
}

enum RouteType{
  srt1
  srt2
  srt3
  srt4
  srt5
  srt6
  srt7
  srt8
}

enum MType{
  mt1
  mt2
  mt3
  mt4
}

enum LicenseType{
  fremium
  essentials
  performance
  plus
  premium
}

enum VideoManufacturersType{
  vmt1
  vmt2
  other
}

type Mutation {
  xampoidedituser(username: String, name: String, group: String, oldgroup: String): String @function(name: “xampoidedituser-${env}")

  xampoiddeleteuser(username: String): String @function(name: “xampoiddeleteuser-${env}")
}
Equartey commented 2 weeks ago

Hi @jamontesg, thank you for opening this issue. Quickly looking at your repro steps, have you tried stopping DataStore when the user logs out, and Starting it back up when logged in?

For example: User logs out > Amplify.DataStore.stop(); > User Logs in > Amplify.DataStore.start();

jamontesg commented 2 weeks ago

Hi @Equartey

This is my logout. function

Future<void> logOut() async {
  try {
    await Amplify.DataStore.clear().then((s) {
      developer.log("DataStore is cleared.");
      signOutCurrentUser();
    });

  } on DataStoreException catch (e) {
    developer.log("Failed to clear DataStore: $e");
  }
}

try with this version with stop:

Future<void> logOut() async {
  try {
    await Amplify.DataStore.stop()
    .then((s) async {
      developer.log("DataStore is Stoped.");
      await Amplify.DataStore.clear().then((s) {
        developer.log("DataStore is cleared.");
        signOutCurrentUser();
      });
    });

  } on DataStoreException catch (e) {
    developer.log("Failed to clear DataStore: $e");
  }
}

don't generate this error.

Equartey commented 2 weeks ago

@jamontesg The second snippet looks correct. To be clear, your are no longer seeing the error, correct?

As for why this fixes the error? When calling .clear() on Android, .stop() gets called for you. iOS does not do that, which is why you should call .stop() before .clear() when restarting DataStore.

jamontesg commented 2 weeks ago

yes this solve the error. maybe We need a equal behavior for iOS/Android or a more detailed documentation. Thanks fir your time @Equartey

Equartey commented 2 weeks ago

@jamontesg glad to hear its resolved. We'll look adjusting the documentation, thanks for the suggestion. For now I'm going to close this issue as resolved.

github-actions[bot] commented 2 weeks ago

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.