You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Amplify DataStore关联模型无法同步远程但本地查询正常的排查求助

问题描述

使用Amplify DataStore时遇到异常:保存关联User的Goal模型时,数据仅能在本地查询到,无法同步至远程数据库;但移除goalOfUser字段时可正常保存到远程(需保留该字段建立双向关联)。执行查询函数能返回保存的数据,但数据的createdAt字段为null。需调试Amplify.DataStore.save()函数定位问题,或指出配置/代码错误。


相关代码

Schema定义

type User @model @auth(rules: [{allow: public}]) {
  id: ID!
  userEmail: AWSEmail!
  userName: String!
  userPassword: String!
  userGoals: [Goal] @hasMany(indexName: "byUser", fields: ["id"])
}

type Goal @model @auth(rules: [{allow: public}]) {
  id: ID!
  goalStart: AWSDateTime!
  goalEnd: AWSDateTime
  goalCategory: CategoryTypes!
  goalCurrentDuration: DurationBeat!
  goalTargetDuration: DurationBeat!
  goalPercentage: Float
  userID: ID! @index(name: "byUser")
  goalActivities: [Activity] @hasMany(indexName: "byGoal", fields: ["id"])
  goalOfUser: User! @belongsTo
}

保存Goal的代码

Future<void> createGoal(String userID, CategoryTypes category,
      DurationBeat targetDuration) async {
    final Goal goal = Goal(
        userID: userID,
        goalCategory: category,
        goalTargetDuration: targetDuration,
        goalCurrentDuration: DurationBeat(
            durationHours: 0, durationMinutes: 0, durationSeconds: 0),
        goalPercentage: 0,
        goalStart: _today, //Local datetime variable
        goalEnd: null, //Null when the goal is current. Date assigned when the user sets new goal.
        goalOfUser: global.currentUser //Globally accessible user instance
);
    await Amplify.DataStore.save(goal);
  }

查询代码

Future<Goal> getLatestGoal(CategoryTypes category, String userId) async {
    final record = await Amplify.DataStore.query(Goal.classType,
        where: Goal.USERID
            .eq(userId)
            .and(Goal.GOALCATEGORY.eq(category))
            .and(Goal.GOALEND.eq(null)),
        sortBy: [Goal.GOALEND.ascending()]);
    return record.first;
  }

返回的数据示例

Goal {id=710ddbeb-89b5-4bcd-9623-8232b4e8a545, goalStart=2022-07-23T04:00:00.000000000Z, goalEnd=null, goalCategory=FITNESS, goalCurrentDuration=DurationBeat {durationSeconds=0, durationMinutes=0, durationHours=0}, goalTargetDuration=DurationBeat {durationSeconds=0, durationMinutes=5, durationHours=1}, goalPercentage=0.0, userID=190c7bd1-02ad-4ab1-970d-49b8e6f7a9f8, goalOfUser=User {id=190c7bd1-02ad-4ab1-970d-49b8e6f7a9f8, userEmail=charlesrichardsonusa@gmail.com, userName=Charbo, userPassword=password, createdAt=2022-07-19T20:23:09.797000000Z, updatedAt=2022-07-23T05:06:18.321000000Z}, createdAt=null, updatedAt=null}

解决方案

一、修复Schema关联配置

@belongsTo字段未指定关联外键,Amplify无法正确映射双向关联。修改Goal模型的goalOfUser字段:

goalOfUser: User! @belongsTo(fields: ["userID"])

明确指定该关联依赖userID字段,确保关联关系映射正确。

二、修正保存代码的关联赋值

保存Goal时不要传入完整User实例,仅需传入User的ID标识,避免循环引用或数据不一致:

final Goal goal = Goal(
    userID: userID,
    goalCategory: category,
    goalTargetDuration: targetDuration,
    goalCurrentDuration: DurationBeat(
        durationHours: 0, durationMinutes: 0, durationSeconds: 0),
    goalPercentage: 0,
    goalStart: _today,
    goalEnd: null,
    // 仅传入User的id,而非完整实例
    goalOfUser: User(id: userID)
);

三、调试DataStore同步问题的方法

  1. 开启详细日志:初始化Amplify时开启verbose日志,查看同步过程中的错误:
Amplify.addPlugin(AmplifyDataStore(modelProvider: ModelProvider.instance));
await Amplify.configure(amplifyconfig);
Amplify.Logging.logLevel = LogLevel.verbose;
// 监听DataStore事件
Amplify.DataStore.observe().listen((event) {
  print('DataStore事件: ${event.eventType} - ${event.item}');
});

通过日志排查同步失败的具体原因(如权限错误、字段验证失败等)。

  1. 查询待同步数据:查看本地是否有未同步的Pending数据:
final pendingGoals = await Amplify.DataStore.query(
  Goal.classType,
  syncStatus: SyncStatus.PENDING
);
print('待同步Goal数量: ${pendingGoals.length}');
  1. 手动触发同步:调用手动同步函数,观察是否抛出异常:
try {
  await Amplify.DataStore.sync();
  print('同步完成');
} catch (e) {
  print('同步失败: $e');
}
  1. 验证远程权限:确认AppSync的API密钥或认证配置正确,确保public权限允许创建关联数据。

四、关于createdAt为null的说明

createdAt和updatedAt由Amplify远程数据库自动生成,本地数据未同步时该字段为null。解决同步问题后,数据同步到远程会自动填充这两个字段。


内容的提问来源于stack exchange,提问作者C RICH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 18:27:21