使用 Dart 而不是 Flutter 从 google firebase rest api 解码 json
Decoding json from google firebase rest api using Dart, not Flutter
我可以从 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
},
{ ...
尝试使用 json解码时,在 dart:convert 中,无法将 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 的包,因为我使用的是预构建的 docker 图像,预装了 Dart 运行时,在 Google Cloud 运行 上。 (老实说,我已经尝试了几个用于 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 反序列化程序包,并注释我的模型 classes 以明确地将这个粗糙的 json 映射到特定的 Dart class 属性。但是我还没有看到支持这种能力的Dart包。
我曾尝试使用“json_serializable: 3.4.1”,但无法生成代码。
在线 json 验证器说由于撇号导致响应格式错误,但我可以相信吗?怀疑我能否转义特殊字符。
解决方案是停止使用 FirebaseClient,因为它没有将 name-value 对括在双引号中。只需使用普通的 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();
错误消息说 response
不是 String
,而是 Map
。
这意味着 Firebase 已经为您解析了 JSON 和 returns parsed 结构。
您不需要使用 jsonDecode
,只需 final orgs = response;
。
我可以从 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
},
{ ...
尝试使用 json解码时,在 dart:convert 中,无法将 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 的包,因为我使用的是预构建的 docker 图像,预装了 Dart 运行时,在 Google Cloud 运行 上。 (老实说,我已经尝试了几个用于 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 反序列化程序包,并注释我的模型 classes 以明确地将这个粗糙的 json 映射到特定的 Dart class 属性。但是我还没有看到支持这种能力的Dart包。
我曾尝试使用“json_serializable: 3.4.1”,但无法生成代码。
在线 json 验证器说由于撇号导致响应格式错误,但我可以相信吗?怀疑我能否转义特殊字符。
解决方案是停止使用 FirebaseClient,因为它没有将 name-value 对括在双引号中。只需使用普通的 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();
错误消息说 response
不是 String
,而是 Map
。
这意味着 Firebase 已经为您解析了 JSON 和 returns parsed 结构。
您不需要使用 jsonDecode
,只需 final orgs = response;
。