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

Firebase Cloud Function模拟器正常 部署报JSON解析错误

问题描述

我编写了一个Cloud Function,用于删除帖子及其关联的comments子集合。该函数在模拟器中可正常执行帖子删除操作,但部署到Firebase时出现以下错误:

i functions: updating Node.js 16 function recursiveDelete(us-central1)...
Function failed on loading user code. This is likely due to a bug in the user code. Error message:
Error: please examine your function logs to see the error cause
Additional troubleshooting documentation can be found at official logging guide page
Functions deploy had errors with the following functions:
recursiveDelete(us-central1)

按照提示查看Google Cloud函数日志,发现报错:

SyntaxError: Unexpected token p in JSON at position 1

at .JSON.parse
at .parse (
/layers/google.nodejs.functions-framework/functions-framework/node_modules/body-parser/lib/types/json.js:89
)

相关代码

Cloud Function 代码

const functions = require("firebase-functions");
const firebase_tools = require('firebase-tools');
const admin = require('firebase-admin');
admin.initializeApp();

/**
 * Initiate a recursive delete of documents at a given path.
 * @param {string} data.path the document or collection path to delete.
 */

exports.recursiveDelete = functions
  .runWith({
    timeoutSeconds: 540,
    memory: '2GB'
  })
  .https.onCall(async (data, context) => {

    const path = data[0].path;
    console.log(`Running cloud function recursiveDelete on ${path}`);

    await firebase_tools.firestore
      .delete(path, {
        project: process.env.GCP_PROJECT,
        recursive: true,
        yes: true,
        token: '...', 
        force: true
      });

    return {
      path: path
    };
    
  });

Flutter客户端调用代码

static Future<void> delete(String ref) async {
  if (FirebaseAuth.instance.currentUser == null) {
    throw Exception('Must be logged in');
  }

  await FirebaseFunctions.instance
      .httpsCallable('recursiveDelete')
      .call([{'path': 'posts/$ref'}])
      .then((value) => logger("Post deleted: ${value.data}"))
      .catchError((error) => logger.error("Failed to delete post: $error"));
}

该功能在模拟器中运行正常,日志输出如下:

I/flutter (26907): [Post] [INFO] Post deleted: {path: posts/Gk4TeWEgZmm0QUcaqTrk}

完整部署堆栈跟踪

=== Deploying to 'sightings-dev'...

i  deploying functions
i  functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i  functions: ensuring required API cloudbuild.googleapis.com is enabled...
✔  functions: required API cloudfunctions.googleapis.com is enabled
✔  functions: required API cloudbuild.googleapis.com is enabled
✔  artifactregistry: required API artifactregistry.googleapis.com is enabled
i  functions: preparing codebase default for deployment
i  functions: preparing functions directory for uploading...
i  functions: packaged /Users/strijdhaftig/sightings/frontend/flutter/sightings/functions (55.13 KB) for uploading
✔  functions: functions folder uploaded successfully
i  functions: updating Node.js 16 function recursiveDelete(us-central1)...
Function failed on loading user code. This is likely due to a bug in the user code. Error message: Error: please examine your function logs to see the error cause. Additional troubleshooting documentation can be found at official logging guide page. Please visit official troubleshooting page for in-depth troubleshooting documentation.

Functions deploy had errors with the following functions:
        recursiveDelete(us-central1)
i  functions: cleaning up build files...

Error: There was an error deploying functions

Having trouble? Try again or contact support with contents of firebase-debug.log

问题原因

报错核心来自两个代码问题:

  1. 硬编码无效token:代码里写死token: '...',线上部署时Functions框架加载代码阶段会尝试解析该字段,无效的占位字符串直接触发JSON解析错误,也就是日志里Unexpected token p in JSON at position 1的来源。本地模拟器对该参数校验宽松,会自动读取本地登录凭证忽略无效传值,所以本地可以正常运行。
  2. Callable函数传参格式不规范:客户端用数组包裹参数[{'path': 'posts/$ref'}]、服务端用data[0].path取值不符合Callable函数的传参设计,线上环境序列化校验更严格,容易触发解析异常。

修复方案

按以下两点修改即可:

  • 删除硬编码的token字段,firebase-tools在Cloud Function运行环境中会自动拉取当前服务的身份凭证,不需要手动传入token。
  • 调整传参格式,去掉数组包裹,直接传递对象参数。

修改后的Cloud Function代码

const functions = require("firebase-functions");
const firebase_tools = require('firebase-tools');
const admin = require('firebase-admin');
admin.initializeApp();

/**
 * Initiate a recursive delete of documents at a given path.
 * @param {string} data.path the document or collection path to delete.
 */

exports.recursiveDelete = functions
  .runWith({
    timeoutSeconds: 540,
    memory: '2GB'
  })
  .https.onCall(async (data, context) => {
    // 直接读取对象属性,不需要数组下标
    const path = data.path;
    console.log(`Running cloud function recursiveDelete on ${path}`);

    await firebase_tools.firestore
      .delete(path, {
        project: process.env.GCP_PROJECT,
        recursive: true,
        yes: true,
        force: true
      });

    return {
      path: path
    };
    
  });

修改后的Flutter调用代码

static Future<void> delete(String ref) async {
  if (FirebaseAuth.instance.currentUser == null) {
    throw Exception('Must be logged in');
  }

  await FirebaseFunctions.instance
      .httpsCallable('recursiveDelete')
      // 直接传入对象,不使用数组包裹
      .call({'path': 'posts/$ref'})
      .then((value) => logger("Post deleted: ${value.data}"))
      .catchError((error) => logger.error("Failed to delete post: $error"));
}

修改完成后重新部署函数即可正常运行。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:09:26