仅使用云功能的 Firebase 存储 svg 上传不起作用 其他格式可以使用 base64

Posted

技术标签:

【中文标题】仅使用云功能的 Firebase 存储 svg 上传不起作用 其他格式可以使用 base64【英文标题】:Firebase storage using cloud function only svg upload not working other format's are okay using base64 【发布时间】:2022-01-23 10:58:04 【问题描述】:

因此,我和我的团队正在努力使用云功能将 SVG 上传和检索到 Firebase 存储。使用我们构建的功能,我们可以上传我们想要的任何图像,除了 SVG。由于某种原因 SVG 无法正常工作,我不知道我们是否编码错误或其他原因

这是我的函数文件

const admin = require("firebase-admin");
const  nanoid  = require("nanoid");
const mime = require("mime-types");
const  validateCauseImageFile  = require("./fileTypeUtils");
const  imageStorageUrlMatch  = require("./regularExpression");

module.exports.imageValidationAndUpload = async (image) => 
  try 
    console.log("Image in base 64", image);
    const bucket = admin.storage().bucket();
    const mimeType = image.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/)
      ? image.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/)[1]
      : null;
    const fileExtension = mime.extension(mimeType);
    console.log(fileExtension);
    const fileName = nanoid() + `.$fileExtension`;
    console.log("Mime type", mimeType);
    const base64EncodedImageString = image.replace(
      /^data:image\/\w+;base64,/,
      ""
    );
    const imageBuffer = Buffer.from(base64EncodedImageString, "base64");
    const result = await validateCauseImageFile(imageBuffer.length, mimeType);

    if (result.success) 
      const token = nanoid();
      const options = 
        gzip: true,
        metadata: 
          contentType: mimeType,
          metadata: 
            firebaseStorageDownloadTokens: token,
          ,
        ,
      ;
      const filePath = "testSvg/" + fileName;
      const file = bucket.file(filePath);
      await file.save(imageBuffer, options);
      const response = await file.getSignedUrl(
        action: "read",
        expires: "03-17-2025", // this is an arbitrary date
      );
      return  success: true, response: response[0] ;

      //   return response;
     else if (image.match(imageStorageUrlMatch)) 
      return  success: true, url: image ;
     else 
      const errorObject =  status: 403, message: result.message ;
      throw errorObject;
    
   catch (err) 
    console.log("show error message : ", err.message);
    return  success: false, message: err.message ;
  
;

如果我上传 png/jpeg/jpg 图像,那么它将被上传并正常工作,但对于 SVG,它将被上传但不会渲染任何内容。在 Firebase 存储控制台存储桶上,它是这样显示的

对于 SVG 图像

对于 png 或任何其他图像

上传过程正常,但 SVG 未正确呈现或检索。这是两个文件的网址

SVG: https://firebasestorage.googleapis.com/v0/b/infaque-playground.appspot.com/o/testSvg%2FaxOmCbg7IY6Q8q8P-5c6D.svg?alt=media&token=6UXNtvtP_ONzQTkmbWypD

PNG: https://firebasestorage.googleapis.com/v0/b/infaque-playground.appspot.com/o/testSvg%2FsbbcDN_8zIpWLfuDyWEYw.png?alt=media&token=I_YsAVHXC3eMIrdGmIiPY

【问题讨论】:

你可以看看*** case。让我知道这是否有帮助! 这个答案适用于 java,我不知道那些 Bytes、Base64 库。此外,如果我使用上传文件按钮上传图像,firebase 存储那么它工作正常,并为我提供 svg 和任何其他文件的预览,但是当我使用必须将其转换为 base64 然后存储它的函数上传它时 您可以参考*** case 和documentation,其中提到了在Node.js 中将base64 解码为图像。 抱歉,一点帮助都没有。任何人都可以帮我解决这个问题 拜托,您能否在问题中发布您正在测试的实际 SVG 图像 data URL?请注意,如果您将图像定义为data:image/svg+xml;base64...,即内容类型为image/svg+xml - 顺便说一句,您用于获取base64 数据的正则表达式,/^data:image\/\w+;base64,/ 不会由于+ 符号而正常工作 - 请尝试类似/^data:image\/(\w|\+)+;base64,/ 的东西。这可能是问题的原因。 【参考方案1】:

根据您的屏幕截图,SVG 图像被传输为 Content-Type image/svg+xml

根据你的代码,这个内容类型计算如下:

const mimeType = image.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/)
      ? image.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/)[1]
      : null;

这意味着你的图片数据 URL 应该是这样的:

data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDEwMCAxMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiIGhlaWdodD0iMTAwcHgiIHdpZHRoPSIxMDBweCI+CjxnPgoJPHBhdGggZD0iTTI4LjEsMzYuNmM0LjYsMS45LDEyLjIsMS42LDIwLjksMS4xYzguOS0wLjQsMTktMC45LDI4LjksMC45YzYuMywxLjIsMTEuOSwzLjEsMTYuOCw2Yy0xLjUtMTIuMi03LjktMjMuNy0xOC42LTMxLjMgICBjLTQuOS0wLjItOS45LDAuMy0xNC44LDEuNEM0Ny44LDE3LjksMzYuMiwyNS42LDI4LjEsMzYuNnoiLz4KCTxwYXRoIGQ9Ik03MC4zLDkuOEM1Ny41LDMuNCw0Mi44LDMuNiwzMC41LDkuNWMtMyw2LTguNCwxOS42LTUuMywyNC45YzguNi0xMS43LDIwLjktMTkuOCwzNS4yLTIzLjFDNjMuNywxMC41LDY3LDEwLDcwLjMsOS44eiIvPgoJPHBhdGggZD0iTTE2LjUsNTEuM2MwLjYtMS43LDEuMi0zLjQsMi01LjFjLTMuOC0zLjQtNy41LTctMTEtMTAuOGMtMi4xLDYuMS0yLjgsMTIuNS0yLjMsMTguN0M5LjYsNTEuMSwxMy40LDUwLjIsMTYuNSw1MS4zeiIvPgoJPHBhdGggZD0iTTksMzEuNmMzLjUsMy45LDcuMiw3LjYsMTEuMSwxMS4xYzAuOC0xLjYsMS43LTMuMSwyLjYtNC42YzAuMS0wLjIsMC4zLTAuNCwwLjQtMC42Yy0yLjktMy4zLTMuMS05LjItMC42LTE3LjYgICBjMC44LTIuNywxLjgtNS4zLDIuNy03LjRjLTUuMiwzLjQtOS44LDgtMTMuMywxMy43QzEwLjgsMjcuOSw5LjgsMjkuNyw5LDMxLjZ6Ii8+Cgk8cGF0aCBkPSJNMTUuNCw1NC43Yy0yLjYtMS02LjEsMC43LTkuNywzLjRjMS4yLDYuNiwzLjksMTMsOCwxOC41QzEzLDY5LjMsMTMuNSw2MS44LDE1LjQsNTQuN3oiLz4KCTxwYXRoIGQ9Ik0zOS44LDU3LjZDNTQuMyw2Ni43LDcwLDczLDg2LjUsNzYuNGMwLjYtMC44LDEuMS0xLjYsMS43LTIuNWM0LjgtNy43LDctMTYuMyw2LjgtMjQuOGMtMTMuOC05LjMtMzEuMy04LjQtNDUuOC03LjcgICBjLTkuNSwwLjUtMTcuOCwwLjktMjMuMi0xLjdjLTAuMSwwLjEtMC4yLDAuMy0wLjMsMC40Yy0xLDEuNy0yLDMuNC0yLjksNS4xQzI4LjIsNDkuNywzMy44LDUzLjksMzkuOCw1Ny42eiIvPgoJPHBhdGggZD0iTTI2LjIsODguMmMzLjMsMiw2LjcsMy42LDEwLjIsNC43Yy0zLjUtNi4yLTYuMy0xMi42LTguOC0xOC41Yy0zLjEtNy4yLTUuOC0xMy41LTktMTcuMmMtMS45LDgtMiwxNi40LTAuMywyNC43ICAgQzIwLjYsODQuMiwyMy4yLDg2LjMsMjYuMiw4OC4yeiIvPgoJPHBhdGggZD0iTTMwLjksNzNjMi45LDYuOCw2LjEsMTQuNCwxMC41LDIxLjJjMTUuNiwzLDMyLTIuMyw0Mi42LTE0LjZDNjcuNyw3Niw1Mi4yLDY5LjYsMzcuOSw2MC43QzMyLDU3LDI2LjUsNTMsMjEuMyw0OC42ICAgYy0wLjYsMS41LTEuMiwzLTEuNyw0LjZDMjQuMSw1Ny4xLDI3LjMsNjQuNSwzMC45LDczeiIvPgo8L2c+Cjwvc3ZnPg==

由于+ 符号,您正在使用的代码不会正确处理该模式:

const base64EncodedImageString = image.replace(
      /^data:image\/\w+;base64,/,
      ""
    );

请查看结果实际上如何包含data:image/svg+xml;base64, 信息作为前缀:

为了成功处理 SVG 用例,您可以将正则表达式修改为:

const base64EncodedImageString = image.replace(
      /^data:image\/(\w|\+)+;base64,/,
      ""
    );

请注意现在如何成功提取 base64:

如果内容类型未设置为image/svg+xml,请考虑将其更改为该值,这也会有所帮助。

【讨论】:

谢谢,伙计,从各处寻找这个答案真的很有帮助,你帮助了我 非常欢迎您@SulmanAzhar,我很高兴能提供帮助并看到答案很有帮助。

以上是关于仅使用云功能的 Firebase 存储 svg 上传不起作用 其他格式可以使用 base64的主要内容,如果未能解决你的问题,请参考以下文章

使用 firebase 功能将图像上传到云存储错误

如何限制 Firebase 云功能仅接受来自 Firebase 托管网站的请求

Firebase 云功能中的 Firebase 存储错误

使用 Firebase 云功能将文件上传到云存储

验证 Firebase 云功能中的存储文件数据

使用云功能从firebase数据库中读取数据而不依赖于事件[重复]