首页 > 解决方案 > 如何在我的 Flutter 应用程序中正确地从 Firebase 函数调用中转换响应

问题描述

我正在通过构建一个简单的膳食计划应用程序来自学 Flutter。我想做的一部分是使用 Firebase 函数来调用 API。我正在使用Spoonacular API,并且我不想将 API 密钥存储在应用程序本身上,因此是 Firebase 后端。

我已经设置了一个名为 的文件cloud_functions.dart,我打算用它来调用我的 Firebase 函数。获取食谱的调用如下:

Future<SearchRecipesComplexResponseBody> getRecipes() async {
  HttpsCallable callable = getCallable('searchRecipes');
  try {
    final HttpsCallableResult<SearchRecipesComplexResponseBody> results = await callable({'number': 20, 'offset': 0});
    print('Results: ');
    print(results);
    print('Results data:');
    print(results.data);
    return results.data;
  } catch (e) {
    print('Error: ');
    print(e);
    return null;
  }
}

HttpsCallable getCallable(String callableName) {
  FirebaseFunctions functions = FirebaseFunctions.instance;
  if (kDebugMode) {
    print('Running in debug mode');
    functions.useFunctionsEmulator(origin: 'http://localhost:5001');
  }
  return functions.httpsCallable(callableName);
}

的代码SearchRecipesComplexResponseBody如下:

import 'package:meal_planner/models/recipe.dart';
import 'package:json_annotation/json_annotation.dart';

part 'search_recipes_complex_response_body.g.dart';

@JsonSerializable()
class SearchRecipesComplexResponseBody {
  final int offset;
  final int number;
  final List<Recipe> results;
  final int totalResults;

  SearchRecipesComplexResponseBody({this.offset, this.number, this.results, this.totalResults});

  factory SearchRecipesComplexResponseBody.fromJson(Map<String, dynamic> json) {
    return _$SearchRecipesComplexResponseBodyFromJson(json);
  }
}

的代码Recipe如下:

@JsonSerializable()
class Recipe {
  final int id;
  @JsonKey(includeIfNull: false)
  final int calories;
  @JsonKey(includeIfNull: false)
  final String carbs;
  @JsonKey(includeIfNull: false)
  final String fat;
  final String image;
  final String imageType;
  @JsonKey(includeIfNull: false)
  final String protein;
  final String title;

  Recipe({@required this.id, this.calories, this.carbs, this.fat, this.image, this.imageType, this.protein, @required this.title});

  factory Recipe.fromJson(Map<String, dynamic> json) {
    return _$RecipeFromJson(json);
  }
}

虽然我确实得到了我期望的数据,但在运行代码时,我得到了这个错误:

type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>'

当我去调试代码时,打破文件print(results)中的行cloud_functions.dart,我看到数据似乎与我期望的格式匹配

未展开 展开

我尝试使用json_serializable实用程序来生成 JSON 序列化代码,但这也不起作用。我试过删除Recipe类中无关的字段无济于事。

我认为这个问题与我在sSearchRecipesComplexResponseBody列表上有一个属性有关Recipe,但我似乎无法弄清楚我在这里做错了什么。据我所知,我可能找错了树。有没有人有任何想法?

检查的资源:

标签: firebaseflutter

解决方案


我想到了

我将getRecipes函数更新cloud_functions.dart为如下:

Future<SearchRecipesComplexResponseBody> getRecipes() async {
  HttpsCallable callable = getCallable('searchRecipes');
  try {
    final HttpsCallableResult results = await callable({'number': 20, 'offset': 0});
    var convertedResult = Map<String, dynamic>.from(results.data);
    SearchRecipesComplexResponseBody data = SearchRecipesComplexResponseBody.fromJson(convertedResult);
    return data;
  } catch (e) {
    print('Error: ');
    print(e);
    return null;
  }
}

我看到我已经fromJson在我的类上定义了一个函数SearchRecipesComplexResponseBody,但我没有利用它。我需要将从 Firebase 返回的响应从 an_InternalLinkedHashMap<dynamic, dynamic>转换为使用的Map<String, dynamic>类型fromJson

我还需要anyMap: true在我的JsonSerializer属性中添加以获取 s 的嵌套列表,Recipe以便为其fromJson. 我不确定为什么会这样。有人有什么想法吗?


推荐阅读