[英]How do I properly call an HTTPs callable function from my app?
[英]How do I properly cast a response from a Firebase Function call in my Flutter app
我正在通過構建一個簡單的膳食計划應用程序來自學 Flutter。 我想做的部分事情是使用 Firebase function 來調用 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>'
當我去調試代碼時,中斷了cloud_functions.dart
文件中的print(results)
行,我看到數據似乎與我期望的格式相匹配
我嘗試使用json_serializable實用程序來生成 JSON 序列化代碼,但這也不起作用。 我嘗試刪除Recipe
class 中的無關字段無濟於事。
我認為這個問題與我在SearchRecipesComplexResponseBody
上有一個屬性有關,它是一個Recipe
的列表,但我似乎無法弄清楚我在這里做錯了什么。 據我所知,我可能找錯了樹。 有沒有人有任何想法?
檢查的資源:
我想到了
我將 cloud_functions.dart 中的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;
}
}
我看到我已經在我的SearchRecipesComplexResponseBody
class 上定義了一個fromJson
function,但我沒有利用它。 我需要將從 Firebase 返回的響應從 _InternalLinkedHashMap _InternalLinkedHashMap<dynamic, dynamic>
轉換為fromJson
使用的Map<String, dynamic>
類型。
我還需要在我的JsonSerializer
屬性中添加anyMap: true
以獲取Recipe
的嵌套列表,以便為其fromJson
。 我不確定為什么會這樣。 有人有什么想法嗎?
您可以使用它從_InternalLinkedHashMap
轉換為Map<String, dynamic>
。 這將使您克服錯誤type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>'
:
HttpsCallable callable = functions.httpsCallable('your-function');
final results = await callable();
final data = Map<String, dynamic>.from(results.data);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.