aws-amplify / amplify-swift

A declarative library for application development using cloud services.
Apache License 2.0
455 stars 196 forks source link

[DataStore.Flutter] Android sourced mutation not working on iOS with schema #3547

Closed lawmicha closed 1 week ago

lawmicha commented 8 months ago

I was able to reproduce this with the following app, schema, and steps.

App

```dart import 'package:amplify_api/amplify_api.dart'; import 'package:amplify_datastore/amplify_datastore.dart'; import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:flutter/material.dart'; import 'package:issue_3654/amplifyconfiguration.dart'; import 'package:issue_3654/models/ModelProvider.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State createState() => _MyAppState(); } class _MyAppState extends State { @override void initState() { super.initState(); _configureAmplify(); } Future _configureAmplify() async { final api = AmplifyAPI(); final ds = AmplifyDataStore(modelProvider: ModelProvider.instance); await Amplify.addPlugins([api, ds]); try { await Amplify.configure(amplifyconfig); } on AmplifyAlreadyConfiguredException { safePrint( 'Tried to reconfigure Amplify; this can occur when your app restarts on Android.'); } observeQueryMessage(); } void observeQueryMessage() { Amplify.DataStore.observeQuery( Message.classType, ).listen((QuerySnapshot snapshot) { safePrint( 'Query snapshot received: ${snapshot.items.length} messages, isSynced: ${snapshot.isSynced}', ); }); } @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData(useMaterial3: true), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { Future saveMessage() async { safePrint("start saving message"); User sender = User( email: 'example@gmail.com', birthdate: TemporalDate(DateTime.now()), gender: Gender.male, nickname: 'nickname', ); await Amplify.DataStore.save(sender); CustomMarker circle = CustomMarker( latitude: 1.0, longitude: 1.0, hostUser: sender, purpose: Purpose.exchange, title: 'title', gatheringTime: TemporalDateTime(DateTime.now()), maxParticipants: 0, minAge: 0, maxAge: 0, numParticipants: 0, ); await Amplify.DataStore.save(circle); Message message = Message( content: 'content', sender: sender, circle: circle, createdOn: TemporalDateTime(DateTime.now().toUtc()), ); await Amplify.DataStore.save(message); safePrint('message saved'); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Hello world'), ], ), ), floatingActionButton: FloatingActionButton( onPressed: saveMessage, tooltip: 'save', child: const Icon(Icons.add), ), ); } } ```

Schema

```graphql enum Gender { male female other } enum UserStatus { student worker doctor other } type User @model @auth( rules: [{ allow: public, operations: [create, read, update, delete] }] ) { id: ID! email: String! phone: String birthdate: AWSDate! gender: Gender! userStatus: UserStatus nickname: String! comment: String imageURL: String messages: [Message] @hasMany(indexName: "MessageByUser", fields: ["id"]) hostedCircles: [CustomMarker] @hasMany(indexName: "CustomMarkerByHostUser", fields: ["id"]) participatedCircles: [CustomMarker] @manyToMany(relationName: "UserCustomMarkerParticipants") } enum Purpose { play food taxi exchange helpme } type CustomMarker @model @auth(rules: [{ allow: public }]) { id: ID! latitude: Float! longitude: Float! hostUserID: ID! @index(name: "CustomMarkerByHostUser") hostUser: User! @belongsTo(fields: ["hostUserID"]) purpose: Purpose! title: String! comment: String gatheringTime: AWSDateTime! maxParticipants: Int! minAge: Int! maxAge: Int! allowGender: Gender numParticipants: Int! messages: [Message] @hasMany(indexName: "MessageByCustomMarker", fields: ["id"]) participants: [User] @manyToMany(relationName: "UserCustomMarkerParticipants") circleImageURL: String } type Message @model @auth(rules: [{ allow: public }]) { id: ID! content: String! createdOn: AWSDateTime! senderID: ID! @index(name: "MessageByUser") sender: User! @belongsTo(fields: ["senderID"]) circleID: ID! @index(name: "MessageByCustomMarker") circle: CustomMarker! @belongsTo(fields: ["circleID"]) } ```

Steps:

  1. Save item on iOS, observe that Android receives the data
  2. Save item on Android, observe that iOS does NOT receive data.

Note: If the app is closed/re-opened on iOS, the data does sync in the next delta sync.

Originally posted by @Jordan-Nelson in https://github.com/aws-amplify/amplify-flutter/issues/3654#issuecomment-1701756960

github-actions[bot] commented 8 months ago

This issue was opened by a maintainer of this repository; updates will be posted here. If you are also experiencing this issue, please comment here with any relevant information so that we're aware and can prioritize accordingly.

lawmicha commented 8 months ago

To reproduce this, use the schema and create a backend with it and replay the requests using AppSync console if we have the selection set readily available (see https://github.com/aws-amplify/amplify-flutter/issues/3654#issuecomment-1978930936). If not, create Flutter app using the sample code from description, and create a Swift app sharing the same backend, and perform saves sourced from the Android Flutter app, to observe the behavior on DataStore Swift v1 app.

ruisebas commented 1 week ago

This is not reproducible in Amplify v2. See https://github.com/aws-amplify/amplify-flutter/issues/3654#issuecomment-2146103984

github-actions[bot] commented 1 week 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. If you wish to keep having a conversation with other community members under this issue feel free to do so.