首页 > 解决方案 > 使用 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
    },
    {  ...

当尝试使用 jsonDecode 时,在 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 的软件包,因为我在 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 验证器说响应由于撇号而格式错误,但我可以相信吗?怀疑我能逃脱特殊字符。

标签: jsonrestdartgoogle-cloud-firestoregoogle-cloud-run

解决方案


错误消息说response不是 a String,而是 a Map。这意味着 Firebase 已经为您解析了 JSON 并返回解析后的结构。

你不需要使用jsonDecode,只需final orgs = response;


推荐阅读