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

在Firebase异步函数中调用另一个异步函数时遇TypeError错误求助

问题排查:调用getViews时触发TypeError错误

错误信息

TypeError: Cannot read properties of undefined (reading 'on')

场景说明

通过getViews、getViewCount和updateCount三个异步函数实现「获取YouTube播放量并存储到Firestore数据库」的功能,但在updateCount内调用getViews时触发上述错误。

相关代码

getViews函数

exports.getViews = functions
  .runWith({
    secrets: ["YOUTUBE_API"]
  })
  .https.onCall(async (data, context) => {
    const count = await getViewCount({}); 
    return count;
  });

updateCount函数

exports.updateCount = functions.https.onRequest(async (req, res) => {
  const viewData = await this.getViews({ "h": "j" }); // 错误触发位置
  const addData = await admin
    .firestore()
    .collection("viewCount")
    .doc("Count")
    .set(viewData)
    .then(() => {
      console.log("Document successfully written!");
    })
    .catch((error) => {
      console.error("Error writing document: ", error);
    });
});

getViewCount函数

const getViewCount = async (arg) => {
  const youtube = google.youtube({
    version: "v3",
    auth: process.env.YOUTUBE_API,
  });

  const count = await youtube.channels.list({
    id: process.env.YOUTUBE_CHANNEL_ID,
    part: "statistics",
  });

  const countData = count.data.items[0].statistics.viewCount;
  return countData;
}

问题原因及修复方案

核心问题

updateCount中使用this.getViews是错误的调用方式:getViews是导出的Cloud Function,并非类的成员方法,在onRequest的执行上下文里this指向undefined,导致this.getViews返回undefined,进而触发读取on属性的错误。

修复方案(二选一即可)

方案1:直接调用getViewCount(推荐)

既然getViews内部本质是调用getViewCount,在updateCount里可以直接复用getViewCount函数,跳过HTTP Callable函数的封装,更高效且避免跨函数调用的问题:

exports.updateCount = functions.https.onRequest(async (req, res) => {
  try {
    const viewData = await getViewCount({}); 
    // 建议将播放量包装为对象存储,避免Firestore存储纯值的潜在问题
    await admin.firestore().collection("viewCount").doc("Count").set({ viewCount: viewData });
    console.log("Document successfully written!");
    res.status(200).send("更新成功");
  } catch (error) {
    console.error("更新失败: ", error);
    res.status(500).send("更新失败");
  }
});

方案2:通过HTTP请求调用getViews(若需复用getViews的权限校验等逻辑)

如果必须调用getViews这个Callable函数,需要通过标准HTTP请求触发,而非直接当作普通函数调用:

const fetch = require('node-fetch'); // 需先安装node-fetch依赖

exports.updateCount = functions.https.onRequest(async (req, res) => {
  try {
    const response = await fetch(`https://${process.env.GCLOUD_PROJECT}.cloudfunctions.net/getViews`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ data: { "h": "j" } }) // Callable函数要求请求体包含data字段
    });
    const result = await response.json();
    if (result.error) throw new Error(result.error.message);
    
    const viewData = result.data;
    await admin.firestore().collection("viewCount").doc("Count").set({ viewCount: viewData });
    console.log("Document successfully written!");
    res.status(200).send("更新成功");
  } catch (error) {
    console.error("更新失败: ", error);
    res.status(500).send("更新失败");
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:35:28