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

使用Firebase Cloud Functions更新Firestore文档极慢问题求助

问题描述

我正在尝试通过Firebase Cloud Functions更新Firestore文档,由于更新无需考虑现有值、以单文档更新为主且冲突风险极低,所以没使用事务。但现在单条测试用例耗时约3分钟,作为初级开发者从没遇到过这么严重的延迟,找不到问题原因。

完整代码

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp();

exports.authenticator = functions.region('asia-northeast1').https.onRequest(async (req, res) => {
  const startTime = new Date().getTime();
  console.log("Function execution started at: ", new Date().toISOString());

  if (req.method !== "POST") {
    console.log("Method Not Allowed");
    return res.status(405).send("Method Not Allowed");
  }

  const data = req.body;

  if (!data || !data.data || !Array.isArray(data.data)) {
    console.log("Bad Request");
    return res.status(400).send("Bad Request");
  }

  res.status(200).send("Processing...");
  console.log("Process started at: ", new Date().toISOString());

  for (const item of data.data) {
    if (!item || !item.phoneNum || !item.authCode) {
      console.log("Invalid data: ", item);
      continue;
    }

    try {
      const updateStart = new Date().getTime();
      console.log("Update started for authCode: ", item.authCode, " at: ", new Date().toISOString());

      await admin.firestore().collection("auth").doc(item.authCode).update({
        phoneNum: item.phoneNum,
        verified: true,
        timestamp: admin.firestore.FieldValue.serverTimestamp()
      });

      const updateEnd = new Date().getTime();
      console.log("Success: ", item.authCode, " at: ", new Date().toISOString(), " Update took: ", (updateEnd - updateStart) / 1000, " seconds");
    } catch (err) {
      console.error(`Error processing ${item.authCode}:`, err);
    }
  }

  const endTime = new Date().getTime();
  console.log("Process ended at: ", new Date().toISOString());
  console.log("Total execution time: ", (endTime - startTime) / 1000, " seconds");
});

运行日志

Function execution started Function execution started at: 2024-07-09T21:28:39.167Z
Process started at: 2024-07-09T21:28:39.188Z
Update started for authCode: 519504f79458497cb8c4709739fbc877 at: 2024-07-09T21:28:39.188Z
Function execution took 80 ms, finished with status code: 200
Success: 519504f79458497cb8c4709739fbc877 at: 2024-07-09T21:31:36.657Z
Update took: 177.469 seconds
Process ended at: 2024-07-09T21:31:36.957Z
Total execution time: 177.79 seconds

环境信息

  • Cloud Functions区域:asia-northeast1
  • Firestore区域:asia-northeast3
  • 请求来源:Google Apps Scripts经Gmail处理后的POST请求
  • 此前在us-central1区域处理更新速度正常

解决方案

1. 核心问题:函数提前终止导致延迟

从日志能看到,函数在发送200响应后就标记为执行完成(耗时80ms),但后续的Firestore更新还在后台运行。Cloud Functions对于已完成响应的函数,会进入闲置状态,资源被回收或优先级降低,导致后续异步操作被严重延迟。

你在代码里先调用res.status(200).send("Processing..."),再执行异步更新,这是关键错误。HTTP函数必须在所有异步操作完成后再发送响应,否则函数会被强制进入闲置,后续操作变慢甚至失败。

2. 修复代码

把发送响应的逻辑移到所有更新操作完成之后:

// 移除原来的res.status(200).send("Processing...");
// ...

// 所有循环完成后再发送响应
res.status(200).send("Processing completed");
console.log("Process ended at: ", new Date().toISOString());
console.log("Total execution time: ", (endTime - startTime) / 1000, " seconds");

3. 区域不匹配的影响

Cloud Functions和Firestore不在同一区域(asia-northeast1 vs asia-northeast3),跨区域调用会增加延迟,但不会达到3分钟这么夸张。如果条件允许,最好把两者调整到同一区域,进一步降低网络耗时。

4. 批量更新优化(可选)

如果后续需要处理多条数据,可以用Promise.all并行执行更新,提升效率:

const updatePromises = [];
for (const item of data.data) {
  if (!item || !item.phoneNum || !item.authCode) {
    console.log("Invalid data: ", item);
    continue;
  }
  updatePromises.push(
    admin.firestore().collection("auth").doc(item.authCode).update({
      phoneNum: item.phoneNum,
      verified: true,
      timestamp: admin.firestore.FieldValue.serverTimestamp()
    })
    .then(() => {
      console.log("Success: ", item.authCode);
    })
    .catch(err => {
      console.error(`Error processing ${item.authCode}:`, err);
    })
  );
}
await Promise.all(updatePromises);

内容的提问来源于stack exchange,提问作者한경완

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:06:18