如何解决使用Dart而不是Flutter从Google Firebase Rest API解码json
我可以从Firebase的Cloud Firestore实例的集合中检索文档列表。响应包含我见过的最详细的json。这是一种味道,...
{
documents: [
{
name: projects/myprojectId/databases/(default)/documents/mycollection/0HC2spBFxEMNUc8VQLFg,fields: {
name: {
stringValue: Jim's Bait Shop},taxId: {
stringValue:
},mailingAddress: {
mapValue: {
fields: {
streetAddress1: {
stringValue:
}
},streetAddress2: {
stringValue:
},state: {
stringValue: NC
},city: {
stringValue: Boone
},zipCode: {
stringValue:
}
}
}
}
},createTime: 2020-08-31T19
:
54: 28.643464Z,updateTime: 2020-09-01T02
:
35: 08.203028Z
},{ ...
在dart:convert中尝试使用jsonDecode时,无法将json响应反序列化为Dart对象的集合。
'_InternalLinkedHashMap<String,dynamic>' is not a subtype of type 'String'
如果我使用cUrl而不是Dart,则json响应看起来就很冗长。
我正在“ package:firebase / firebase_io.dart”中使用FirebaseClient进行身份验证并读取集合。
我试图构建一个“ reviver”功能,但是jsonDecode不接受它,所以我不确定如何弄乱它。
无论如何,我没有在文档中看到太多有关如何将这种冗长的json响应编组到Dart对象中的指导。我怀疑此服务器端Dart有点新领域。我想避免使用需要Flutter的软件包,因为我在Google Cloud Run上使用了预构建的Docker映像,并预安装了Dart运行时。 (说实话,我已经尝试了一些用于Firestore的Flutter软件包和Flutter Docker映像。)我会采纳您的任何建议。
下面是我一直用于测试的文件。
import 'package:firebase/firebase_io.dart';
import 'credentials.dart'; // borrowed from a SO post
import 'dart:convert';
const base = 'https://firestore.googleapis.com/v1/projects/';
void main() async {
// get private key...
final credential = await Credentials.fetch(); // string
final fbClient = FirebaseClient(credential);
final path = base + 'my_project_id/databases/(default)/documents/my_collection'
'?mask.fieldPaths=name&mask.fieldPaths=taxId&mask.fieldPaths=mailingAddress&orderBy=orgId';
final response = await fbClient.get(path);
print(response);
final orgs = jsonDecode(response); // unhandled exception
fbClient.close();
}
我认为我可能需要切换到更复杂的json反序列化程序包,并注释我的模型类,以将这个粗糙的json显式映射到特定的Dart类属性。但是我还没有看到支持这种功能的Dart程序包。
我尝试使用“ json_serializable:3.4.1”,但未能使代码生成正常工作。
在线json验证程序说,由于撇号导致响应的格式有误,但我可以相信吗?怀疑我可以逃脱特殊字符。
解决方法
错误消息指出response
不是String
,而是Map
。
这意味着Firebase已经为您解析了JSON并返回了 parsed 结构。
您不需要使用jsonDecode
,只需使用final orgs = response;
。
解决方案是停止使用FirebaseClient,因为它没有将名称/值对用双引号引起来。只需使用普通的http即可。
import 'package:http/http.dart' as http;
const base = 'https://firestore.googleapis.com/v1/projects/';
void main() async {
//
final uri = base + 'myproject/databases/(default)/documents/mycollection' +
'?mask.fieldPaths=name&mask.fieldPaths=taxId&mask.fieldPaths=mailingAddress&orderBy=orgId&alt=json';
var response = await http.get(uri);
// print(response.body);
var json = jsonDecode(response.body)['documents'] as List;
List l = json.map((o) => MyModelClass.fromJson(o)).toList();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。