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

Flutter iOS应用使用AWS Amplify创建用户设置失败问题排查

概述

我正在开发一款基于AWS的Flutter iOS应用,当前遇到的问题是为用户添加持久化设置模型时出错。每个用户应对应一个由其选择项生成的设置模型,和常规应用逻辑一致。

具体来说,我需要一个名为randomPhotoOffset的布尔型设置项。有人建议我使用Amplify和DynamoDB存储用户设置,因为相比仅使用Cognito,它具备可扩展性且提供更多选项。

开发环境与版本信息
  • 使用Amplify Gen 1及CLI
  • amplify_flutter: ^2.6.0
  • amplify_auth_cognito: ^2.5.0
  • amplify_api: ^2.6.0
  • amplify_datastore: ^2.6.0
  • Flutter SDK: ^3.5.4(已更新pubspec.yaml,所有包均为最新版本,无版本冲突)

测试环境:搭载M4 Pro芯片的Mac上的iPhone 16 Pro模拟器

问题详情

点击按钮更改设置时会触发以下错误:

Exception updating user settings: ApiOperationException {
"message": "No modelProvider found",
"recoverySuggestion": "Pass in a modelProvider instance while instantiating APIPlugin"
}

相关代码

main.dart

该函数在WidgetsFlutterBinding.ensureInitialized()之后、runApp()之前调用。

Future<void> configureAmplify() async {
  try {
    final authPlugin = AmplifyAuthCognito();
    final apiPlugin = AmplifyAPI();
    final dataStorePlugin =
        AmplifyDataStore(modelProvider: ModelProvider.instance);

    Amplify.addPlugins(
      [authPlugin, dataStorePlugin, apiPlugin],
    );
    await Amplify.configure(amplifyConfig);

    // Start DataStore to register the model provider for GraphQL operations.
    await Amplify.DataStore.start();
  } on Exception catch (e) {
    Log.e("Error configuring Amplify: $e");
  }
}

settings.dart

这是按钮点击时调用的唯一相关函数,切换后立即生效,无需保存按钮

Future<void> _toggleRandomPhotoOffset(bool newValue) async {
    setState(() {
      _randomPhotoOffset = newValue;
    });
    try {
      // Retrieve the current user's ID from Amplify Auth.
      final authUser = await Amplify.Auth.getCurrentUser();
      await updateUserSettings(
        userId: authUser.userId,
        randomPhotoOffset: newValue,
      );
    } catch (e) {
      Log.e("Error retrieving user or updating settings: $e");
    }
  }

settings_service.dart

updateUserSettings的定义如下

Future<void> updateUserSettings({
  required String userId,
  required bool randomPhotoOffset,
}) async {
  // Create a new UserSettings object.
  final settings = UserSettings(
    userId: userId,
    randomPhotoOffset: randomPhotoOffset,
  );

  try {
    final request = ModelMutations.create(settings);
    final response = await Amplify.API.mutate(request: request).response;
    if (response.errors.isEmpty) {
      Log.i("User settings updated: ${response.data}");
    } else {
      Log.e("Errors updating user settings: ${response.errors}");
    }
  } catch (e) {
    Log.e("Exception updating user settings: $e");
  }
}

schema.graphql

这是Amplify所需的模型定义

type UserSettings @model {
  id: ID!
  userId: String!
  randomPhotoOffset: Boolean
}

注:编写该模型后,我执行了amplify push和amplify codegen models,已成功生成ModelProvider.dart和UserSettings.dart,未对其进行任何修改。

已尝试的方案

方案1

尝试通过AI解决问题,但给出的方案不可行。例如建议修改settings_service如下:

Future<void> updateUserSettings({
  required String userId,
  required bool randomPhotoOffset,
}) async {
  final settings = UserSettings(
    userId: userId,
    randomPhotoOffset: randomPhotoOffset,
  );

  try {
    final request = ModelMutations.create(
      settings,
      modelProvider: ModelProvider.instance,
    );
    final response = await Amplify.API.mutate(request: request).response;
    if (response.errors.isEmpty) {
      print("User settings updated: ${response.data}");
    } else {
      print("Errors updating user settings: ${response.errors}");
    }
  } catch (e) {
    print("Exception updating user settings: $e");
  }
}

但ModelMutations.create并不支持modelProvider参数,问题仍未解决,我认为问题出在main.dart的配置中。

方案2

修改configureAmplify()为如下代码:

void _configureAmplify() async {
    try {
      final authPlugin = AmplifyAuthCognito();
      final apiPlugin = AmplifyAPI();

      Amplify.addPlugins([authPlugin, apiPlugin]);

      await Amplify.configure(amplifyconfig);
      setState(() {
        _amplifyConfigured = true;
      });
    } catch (e) {
      print("Amplify configuration failed: $e");
    }
  }

虽然没有语法错误,但上述错误仍会出现。

解决方案

错误提示明确指出需要在实例化APIPlugin时传入modelProvider实例,当前代码中AmplifyAPI()初始化时未传入该参数,这就是问题根源。

步骤1:修正Amplify配置

修改main.dart中的configureAmplify函数,在创建AmplifyAPI时传入modelProvider:

Future<void> configureAmplify() async {
  try {
    final authPlugin = AmplifyAuthCognito();
    // 传入ModelProvider.instance给APIPlugin
    final apiPlugin = AmplifyAPI(modelProvider: ModelProvider.instance);
    final dataStorePlugin =
        AmplifyDataStore(modelProvider: ModelProvider.instance);

    Amplify.addPlugins(
      [authPlugin, dataStorePlugin, apiPlugin],
    );
    await Amplify.configure(amplifyConfig);

    await Amplify.DataStore.start();
  } on Exception catch (e) {
    Log.e("Error configuring Amplify: $e");
  }
}

步骤2:优化设置更新逻辑

当前代码使用ModelMutations.create会每次生成新的UserSettings记录,建议先查询用户已有设置,存在则更新,不存在再创建,避免重复数据:

Future<void> updateUserSettings({
  required String userId,
  required bool randomPhotoOffset,
}) async {
  try {
    // 查询用户已有的设置记录
    final query = ModelQueries.list(UserSettings.classType, 
      UserSettings.USER_ID.eq(userId)
    );
    final queryResponse = await Amplify.API.query(request: query).response;
    final existingSettings = queryResponse.data?.items;

    if (existingSettings != null && existingSettings.isNotEmpty) {
      // 更新已有记录
      final updatedSettings = existingSettings.first.copyWith(
        randomPhotoOffset: randomPhotoOffset
      );
      final updateRequest = ModelMutations.update(updatedSettings);
      final updateResponse = await Amplify.API.mutate(request: updateRequest).response;
      if (updateResponse.errors.isEmpty) {
        Log.i("User settings updated: ${updateResponse.data}");
      } else {
        Log.e("Errors updating user settings: ${updateResponse.errors}");
      }
    } else {
      // 创建新记录
      final settings = UserSettings(
        userId: userId,
        randomPhotoOffset: randomPhotoOffset,
      );
      final createRequest = ModelMutations.create(settings);
      final createResponse = await Amplify.API.mutate(request: createRequest).response;
      if (createResponse.errors.isEmpty) {
        Log.i("User settings created: ${createResponse.data}");
      } else {
        Log.e("Errors creating user settings: ${createResponse.errors}");
      }
    }
  } catch (e) {
    Log.e("Exception updating user settings: $e");
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 12:47:32