Flutter中fetchAndSetProducts函数抛出FormatException异常的排查求助
解决Flutter中Fetch产品数据的FormatException问题
看起来你遇到的核心问题是HTTP请求返回了非JSON格式的内容(大概率是404错误页面),导致json.decode解析时抛出FormatException。咱们一步步来排查和解决:
1. 先添加响应状态码检查,定位实际返回内容
你的代码目前直接尝试解码响应体,但没有判断请求是否成功。如果请求返回404(资源未找到)、401(权限不足)等错误状态,服务器返回的是HTML错误页面而非JSON,这就会触发解码失败。
修改代码,先检查状态码并打印错误响应:
Future<void> fetchAndSetProducts() async { final url = Uri.https('flutter-project-c43e5-default-rtdb.firebaseio.com', '/products.json?auth=$authToken'); try { final response = await http.get(url); // 新增:检查响应状态码,捕获错误请求 if (response.statusCode >= 400) { print('请求失败,状态码:${response.statusCode}'); print('返回内容:${response.body}'); // 这里会看到"not found"相关的HTML内容 throw Exception('获取产品失败:${response.statusCode}'); } final extractedData = json.decode(response.body) as Map<String, dynamic>; if (extractedData == null) { return; } final List<Product> loadedProducts = []; extractedData.forEach((prodId, prodData) { loadedProducts.add(Product( id: prodId, title: prodData['title'], description: prodData['description'], price: prodData['price'], isFavorite: prodData['isFavorite'], imageUrl: prodData['imageUrl'], )); }); _items = loadedProducts; notifyListeners(); } catch (error) { rethrow; // 用rethrow保留原始错误栈,便于调试 } }
运行后查看控制台打印,就能明确是URL错误、权限问题还是数据库节点不存在。
2. 排查URL与AuthToken的正确性
- 验证URL:把打印出来的
url复制到浏览器或Postman中直接访问,确认:- Firebase项目ID(
flutter-project-c43e5)是否正确 - 路径
/products.json是否对应你数据库中的节点(有没有拼写错误、大小写错误)
- Firebase项目ID(
- 检查AuthToken:确保
authToken是从Firebase Auth正确获取的有效令牌,没有过期。如果令牌无效,Firebase会返回权限错误,也可能触发404。
3. 检查Firebase数据库规则
如果URL和令牌都没问题,那大概率是数据库规则限制了读取权限。默认的Firebase Realtime Database规则是禁止未授权访问的:
{ "rules": { ".read": false, ".write": false } }
你可以暂时修改规则测试(上线前一定要改回安全规则):
{ "rules": { "products": { // 只开放products节点的权限 ".read": "auth != null", // 允许已认证用户读取 ".write": "auth != null" } } }
测试阶段也可以临时开放(仅限测试环境!):
{ "rules": { ".read": true, ".write": true } }
总结
按照这个流程:先通过状态码检查看到实际错误内容,再逐一验证URL、令牌、数据库规则,就能快速定位并解决这个FormatException问题。
内容的提问来源于stack exchange,提问作者Naman Arya
相关产品推荐
相关产品推荐

