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

Android应用集成AWS Amplify后无法从DynamoDB获取数据

问题分析

你遇到的错误核心是:Amplify DataStore依赖_deleted、_lastChangedAt、_version三个系统字段实现数据同步和订阅功能,但你的DynamoDB表中没有这些字段,导致GraphQL订阅请求的字段校验失败。

解决方案

根据你的需求(保留现有表/重新创建表),提供三种可行方案:

方案1:通过Amplify重新创建带系统字段的表(推荐)

如果允许重构数据表,直接用Amplify的GraphQL schema定义模型,Amplify会自动生成包含所需系统字段的DynamoDB表和GraphQL API:

  1. 在本地项目的amplify/backend/api/<api-name>/schema.graphql中定义Todo模型:
type Todo @model {
  id: ID!
  name: String!
  priority: Int!
  updatedAt: AWSDateTime!
}
  1. 运行amplify push命令,Amplify会自动创建带_deleted、_lastChangedAt、_version字段的DynamoDB表,并更新GraphQL API。
  2. 重新生成Android端的模型类:运行amplify codegen models,替换项目中现有的Todo类。
  3. 重新运行查询代码即可正常工作。

方案2:给现有DynamoDB表添加缺失字段

如果必须保留现有表,需要手动补全系统字段并更新GraphQL配置:

  1. 登录AWS控制台,找到你的DynamoDB表,添加三个字段:
    • _deleted:布尔类型,默认值设为false
    • _lastChangedAt:数字类型(存储Unix时间戳)
    • _version:数字类型,默认值设为1
  2. 更新本地GraphQL schema,显式声明这些字段:
type Todo @model {
  id: ID!
  name: String!
  priority: Int!
  updatedAt: AWSDateTime!
  _deleted: Boolean
  _lastChangedAt: Int
  _version: Int
}
  1. 运行amplify push更新API,再运行amplify codegen models更新Android模型类。
  2. 给现有表中的所有数据补全这三个字段的值(比如_deleted设为false,_version设为1,_lastChangedAt设为当前时间戳)。

方案3:跳过DataSync,直接操作DynamoDB

如果不需要离线同步和订阅功能,可直接使用Amplify的DynamoDB客户端或GraphQL查询,绕过DataStore的系统字段校验:

直接使用GraphQL查询示例

private void fetchTodo() {
    String todoId = "your-todo-id";

    Amplify.API.query(
        ModelQuery.get(Todo.class, todoId),
        response -> {
            if (response.hasData()) {
                Todo todo = response.getData();
                runOnUiThread(() -> {
                    name.setText(todo.getName());
                    // 注意:ordinal()返回int,需转成字符串再设置
                    priority.setText(String.valueOf(todo.getPriority().ordinal()));
                    update.setText(String.valueOf(todo.getUpdatedAt().getOffsetTotalSeconds()));
                });
            } else {
                Log.i("Tutorial", "No Todo found with the specified ID.");
            }
        },
        failure -> Log.e("Tutorial", "Could not query", failure)
    );
}

直接使用DynamoDB客户端示例

private void fetchTodoDirectly() {
    String todoId = "your-todo-id";
    HashMap<String, AttributeValue> itemKey = new HashMap<>();
    itemKey.put("id", AttributeValue.builder().s(todoId).build());

    Amplify.DynamoDB.getItem(
        "YourTableName",
        itemKey,
        result -> {
            Map<String, AttributeValue> item = result.getItem();
            if (item != null) {
                String name = item.get("name").getS();
                int priority = Integer.parseInt(item.get("priority").getN());
                String updatedAt = item.get("updatedAt").getS();
                
                runOnUiThread(() -> {
                    name.setText(name);
                    priority.setText(String.valueOf(priority));
                    update.setText(updatedAt);
                });
            }
        },
        error -> Log.e("Tutorial", "Failed to get item", error)
    );
}
额外代码修正

你的原代码中priority.setText(todo.getPriority().ordinal());存在问题:setText()方法接收字符串参数,直接传入int会被当成资源ID导致崩溃,需修改为priority.setText(String.valueOf(todo.getPriority().ordinal()))。

内容的提问来源于stack exchange,提问作者Bikash Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 23:18:19