如何将Firebase自定义令牌发送至客户端并解决解析报错问题?
自定义令牌传输时客户端JSON解析失败问题
客户端报错:
I/flutter ( 6747): FormatException: Unexpected end of input (at character 1)
后端PHP代码(已生成JWT格式的customToken)
$customToken = $data . '.' . $encoded_signature; try { // Send the custom token back to the client as JSON $response = [ 'token' => $customToken, ]; header('Content-Type: application/json'); echo json_encode($response); } catch (\Exception $e) { // Handle errors and send an error response if needed http_response_code(500); $errorResponse = ['error' => 'Token creation failed']; echo json_encode($errorResponse); }
客户端Flutter代码
Future signInWithToken() async { try { final res = await http.get(Uri.parse(API.sendTokenInfo)); if (res.statusCode == 200) { // Parse the JSON response to extract the token final Map<String, dynamic> data = json.decode(res.body); final String token = data['token']; _auth.signInWithCustomToken(token); return token; } else { // Handle the error, e.g., display an error message print('Failed to fetch custom token: ${res.statusCode}'); return null; } } catch (e) { print(e.toString()); throw Exception('something went wrong'); } }
问题分析
这个错误说明客户端接收到的响应内容为空或不是有效的JSON,核心原因集中在后端输出异常或客户端请求环节:
- 后端可能输出了多余内容(如文件开头的空格、换行),导致JSON格式被破坏;
json_encode可能失败但未被捕获(默认不抛出异常,仅返回false);- 服务器未正确返回内容,或客户端请求的API地址无效;
- 令牌内容包含非UTF-8字符,导致JSON编码失败。
解决方案
1. 修复后端输出逻辑
修改PHP代码,确保JSON输出完整且无多余内容:
$customToken = $data . '.' . $encoded_signature; try { $response = [ 'token' => $customToken, ]; // 验证JSON编码结果 $jsonResponse = json_encode($response); if ($jsonResponse === false) { throw new \Exception('JSON编码失败: ' . json_last_error_msg()); } header('Content-Type: application/json; charset=utf-8'); echo $jsonResponse; exit; // 终止脚本,避免后续代码输出多余内容 } catch (\Exception $e) { http_response_code(500); $errorResponse = ['error' => '令牌生成失败: ' . $e->getMessage()]; echo json_encode($errorResponse); exit; }
同时检查PHP文件开头是否存在BOM(字节顺序标记)或多余空格,这些会破坏JSON格式。
2. 客户端调试排查
在JSON解析前打印响应内容,确认服务器返回的实际数据:
if (res.statusCode == 200) { print('响应内容: ${res.body}'); // 新增调试代码 final Map<String, dynamic> data = json.decode(res.body); final String token = data['token']; _auth.signInWithCustomToken(token); return token; }
- 如果打印为空:检查服务器是否执行到输出语句,或API地址是否正确;
- 如果打印非JSON内容:检查后端字符编码是否为UTF-8,或令牌是否包含特殊字符。
3. 验证API请求有效性
用Postman或浏览器直接访问API.sendTokenInfo对应的地址,确认返回的是标准JSON格式(如{"token":"xxx.yyy.zzz"}),同时检查跨域配置(若存在跨域场景)。
内容的提问来源于stack exchange,提问作者Jabu
相关产品推荐
相关产品推荐

