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

Firestore新建含Cloud Storage图片URL文档时如何生成缩略图?

前置依赖安装

执行以下命令安装图片处理库:

npm install sharp @types/sharp

完整实现代码

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import * as sharp from "sharp";

admin.initializeApp();
const firestore = admin.firestore();
const storage = admin.storage();

export const generateThumbnailOnCreate = functions
  // 配置云函数最小内存256MB,避免图片处理时内存不足
  .runWith({ memory: "256MB" })
  .firestore.document("missions/{missionId}")
  .onCreate(async (snap, context) => {
    const doc = snap.data();
    const missionImgUrl = doc.mission_img_url;
    // 无图片URL直接跳过处理
    if (!missionImgUrl) return;

    try {
      // 步骤1:从下载URL解析出存储桶和文件路径
      const urlObj = new URL(missionImgUrl);
      const pathParts = urlObj.pathname.split("/");
      const bucketName = pathParts[3];
      // 解码文件路径
      const fullFilePath = decodeURIComponent(pathParts[4]);
      const bucket = storage.bucket(bucketName);
      const originalFile = bucket.file(fullFilePath);

      // 步骤2:下载原图到内存
      const [originalFileBuffer] = await originalFile.download();

      // 步骤3:生成100px宽度的缩略图,高度自适应
      const thumbnailBuffer = await sharp(originalFileBuffer)
        .resize({ width: 100, withoutEnlargement: true }) // 小图不强制放大
        .jpeg({ quality: 80 }) // 可根据需求调整格式和质量
        .toBuffer();

      // 步骤4:生成缩略图存储路径,和原图同目录
      const pathSegments = fullFilePath.split("/");
      const fileName = pathSegments.pop() || "";
      const [name, ext] = fileName.split(".");
      const thumbFileName = `${name}_thumb.${ext}`;
      const thumbFilePath = [...pathSegments, thumbFileName].join("/");
      const thumbFile = bucket.file(thumbFilePath);

      // 步骤5:上传缩略图到Storage
      await thumbFile.save(thumbnailBuffer, {
        contentType: "image/jpeg",
        public: false, // 和原图权限保持一致即可
      });

      // 步骤6:获取缩略图永久下载URL
      const [thumbnailImgUrl] = await thumbFile.getSignedUrl({
        action: "read",
        expires: "03-01-2500", // 设置极长过期时间等价永久有效,和客户端getDownloadUrl效果一致
      });

      // 步骤7:更新回Firestore文档
      await snap.ref.update({ thumbnail_img_url: thumbnailImgUrl });
      console.log("缩略图生成并更新成功");
    } catch (err) {
      console.error("缩略图处理失败:", err);
    }
  });

注意事项

  • 云函数默认服务账号需要拥有Storage的读写权限,通常默认初始化的admin权限已经满足
  • 如果需要生成PNG/GIF等格式的缩略图,修改sharp的输出配置即可
  • 若原图可能不存在,可增加originalFile.exists()判断逻辑避免报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:15:02