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

在Cloud Functions中如何从Firestore文档获取纯净原始数据?

在Cloud Functions中获取Firestore触发器的原始数据

当然可行。Cloud Functions里Firestore触发器返回的事件数据是Firestore的Protobuf格式,所以会带stringValue、arrayValue这类类型包装字段,我们可以通过两种方式拿到和原文档一致的原始数据:

方法1:用Firestore SDK内置转换工具

Firestore Node.js SDK自带Firestore.convertFromProto()方法,能直接把Protobuf格式的结构转成普通JS对象,省心又靠谱。

修改你提供的示例代码:

const Firestore = require('@google-cloud/firestore');

const firestore = new Firestore({
  projectId: process.env.GOOGLE_CLOUD_PROJECT,
});

exports.makeUpperCase = event => {
  // 一键转成原始数据结构
  const rawData = Firestore.convertFromProto(event.value);
  
  const resource = event.value.name;
  const affectedDoc = firestore.doc(resource.split('/documents/')[1]);

  const curValue = rawData.original; // 直接拿值,不用再取stringValue
  const newValue = curValue.toUpperCase();

  if (curValue !== newValue) {
    console.log(`Replacing value: ${curValue} --> ${newValue}`);

    return affectedDoc.set({
      original: newValue,
    });
  } else {
    console.log('Value is already upper-case.');
  }
};

方法2:自己写解析函数

如果不想依赖SDK的内置方法,可以自己写个递归解析函数,处理所有Firestore支持的数据类型:

function parseFirestoreProto(fields) {
  if (!fields) return null;
  
  return Object.entries(fields).reduce((result, [key, value]) => {
    if (value.stringValue !== undefined) {
      result[key] = value.stringValue;
    } else if (value.integerValue !== undefined) {
      result[key] = parseInt(value.integerValue, 10);
    } else if (value.doubleValue !== undefined) {
      result[key] = parseFloat(value.doubleValue);
    } else if (value.booleanValue !== undefined) {
      result[key] = value.booleanValue;
    } else if (value.arrayValue?.values) {
      result[key] = value.arrayValue.values.map(item => parseFirestoreProto(item.fields || { _: item }));
    } else if (value.mapValue?.fields) {
      result[key] = parseFirestoreProto(value.mapValue.fields);
    } else if (value.nullValue !== undefined) {
      result[key] = null;
    }
    return result;
  }, {});
}

// 在函数里调用
exports.makeUpperCase = event => {
  const rawData = parseFirestoreProto(event.value.fields);
  const curValue = rawData.original;
  // 后续逻辑和之前一致
};

注意事项

  • 优先用第一种方法,官方维护的工具能覆盖Timestamp、GeoPoint等复杂类型,不用自己操心边界情况。
  • 自定义函数适合需要特殊解析逻辑的场景,但要自己处理所有可能的数据类型,避免遗漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:05:18