You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何上传json.encode字符串到Firebase?代码报错及响应解析问题

问题解决方案

一、正确的Firebase数据上传方式

你第二个代码里的错误是因为set({str})把字符串包装成了Set集合,而Firebase的set()方法需要传入Map<String, dynamic>类型的参数。其实完全不需要用json.encode转成字符串,直接构建Map传入即可——Firebase SDK会自动处理数据的序列化。

修正后的代码可以参考你最初的写法,或者优化后的Map构建方式:

try {
  // 直接构建嵌套Map,无需转JSON字符串
  final data = {
    DateFormat('MM-dd-yyyy').format(dateTime): {
      'host-$listOfAcceptedPlayers': {
        'levels': [selectedRange.start, selectedRange.end],
        'listOfAcceptedPlayers': [listOfAcceptedPlayers],
        'numOfPlayers': _amountOfPlayers[_selectedPlayer].toString(),
        'time': [
          DateFormat('HHmm').format(dateTime),
          DateFormat('HHmm').format(endDateTime)
        ],
      }
    }
  };

  await _firestore.collection('activity').doc(docID).set(
    data,
    SetOptions(merge: true),
  );
} catch (e) {
  print('上传错误: $e');
}

如果一定要用JSON字符串转成Map(不推荐,属于冗余操作),可以这样做:

// 先构建Map,转成JSON字符串后再转回Map
String str = json.encode(date);
Map<String, dynamic> data = json.decode(str);
await _firestore.collection('activity').doc(docID).set(data, SetOptions(merge: true));

二、关于原响应无法解析的问题

Firebase返回的响应本身就是标准JSON格式,出现“无法解析非JSON响应”大概率是你的响应处理逻辑有问题:

  • 检查是否在异步操作中正确使用await获取响应
  • 确认是否误将响应的某个非JSON属性当成了响应主体
  • 可以打印完整的响应内容,排查是否有格式错误或异常返回

目前来看,上传数据的逻辑本身不需要依赖JSON字符串转义,用原生Map上传是最稳妥的。

三、动态字段host-$listOfAcceptedPlayers的获取方法

因为这个字段名是动态生成的,读取数据时可以通过遍历Map的键或条目来访问下层数据:

方法1:遍历Map的keys

// 假设从Firebase获取到的文档数据为docData
final dateKey = DateFormat('MM-dd-yyyy').format(targetDateTime);
final hostMap = docData[dateKey] as Map<String, dynamic>;

// 获取动态的host字段名
String hostKey = hostMap.keys.firstWhere(
  (key) => key.startsWith('host-'),
  orElse: () => '',
);

// 访问下层数据
if (hostKey.isNotEmpty) {
  final hostData = hostMap[hostKey] as Map<String, dynamic>;
  final levels = hostData['levels'];
  final playerList = hostData['listOfAcceptedPlayers'];
  // ...处理其他字段
}

方法2:通过entries遍历

final dateKey = DateFormat('MM-dd-yyyy').format(targetDateTime);
final hostMap = docData[dateKey] as Map<String, dynamic>;

for (final entry in hostMap.entries) {
  if (entry.key.startsWith('host-')) {
    final hostData = entry.value as Map<String, dynamic>;
    // 处理hostData中的数据
    break; // 找到目标字段后跳出循环
  }
}

内容的提问来源于stack exchange,提问作者Pierre Louet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:07:36