【问题标题】:Blob not Blob - how to store a canvas.toBlob in a firestore Blob?Blob 不是 Blob - 如何将 canvas.toBlob 存储在 Firestore Blob 中?
【发布时间】:2020-08-28 23:40:57
【问题描述】:

我有一个 jpeg 的 Javascript native Blob,我想将其存储为 firestore blob

当然,Firestore 会说“FirebaseError:使用无效数据调用的函数 DocumentReference.update()。不支持的字段值:自定义 Blob 对象(在文档中的字段图像中找到...”

有没有办法从 javascript-blob 转换为 firestore-blob?

canvas.toBlob(async (blob)=> {
    console.info(`Converting to blob: ${blob.constructor.name} and storing to firestore...`);
    await myselfRef.update({
        image: blob
    }, 'image/jpeg', 0.4));

【问题讨论】:

    标签: javascript firebase google-cloud-firestore blob


    【解决方案1】:

    要将 JavaScript Blob 转换为 Firestore Blob,您必须按照以下步骤操作:

    1. 使用 your_blob.arrayBuffer() 将 JavaScript Blob 转换为 ArrayBuffer。
    2. 将刚刚获得的 ArrayBuffer 包装到 Uint8Array 中,方法是将其作为单个参数传递给 the constructor
    3. 使用 firebase.firestore.Blob.fromUint8Array(your_array) 方法最终创建 Firestore Blob。

    如果您想执行从 Firestore Blob 到 JavaScript Blob 的逆变换,您几乎必须执行相反的操作:

    1. 使用 firestore_blob.toUint8Array() 将 Firestore Blob 转换为 Uint8Array。
    2. 使用 the constructor 使用数组创建 JavaScript Blob。请记住,您必须使用数组列表来调用它,例如,new Blob([my_array])

    这是一个实践中的例子。函数save() 用于将画布的内容保存到Firestore。并且,load() 函数再次将它们加载到画布中。

    const canvas = document.querySelector('canvas');
    const context = canvas.getContext('2d');
    const db = firebase.firestore();
    
    function save() {
      canvas.toBlob(async blob => {
        const blob_url = URL.createObjectURL(blob);
        const ref = db.collection('blob').doc('blob');
        const array_buffer = await blob.arrayBuffer();
        const uint8_array = new Uint8Array(array_buffer);
        const firebase_blob = firebase.firestore.Blob.fromUint8Array(uint8_array);
        ref.update({
          image: firebase_blob,
        });
      });
    }
    
    async function load() {
      const ref = db.collection('blob').doc('blob');
      const doc = await ref.get();
      const firebase_blob = doc.get('image');
      const uint8_array = firebase_blob.toUint8Array();
      const blob = new Blob([uint8_array]);
      const blob_url = URL.createObjectURL(blob);
      const image = new Image();
      image.onload = () => {
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.drawImage(image, 0, 0);
        URL.revokeObjectURL(blob_url);
      }
      image.src = blob_url;
    }
    

    【讨论】:

    • 不确定这是否兼容跨浏览器,因为目前 Safari 或 Firefox Android 似乎不支持 Blob.arrayBuffer
    • 跟进之前的评论和一些测试......尽管文档说它似乎支持所有现代浏览器(包括 FF Android 85,目前列为不支持):@987654335 @见stackoverflow.com/a/55204517/720204
    猜你喜欢
    • 2019-05-01
    • 1970-01-01
    • 2013-07-05
    • 2011-10-10
    • 2016-12-07
    • 2012-03-02
    • 2016-03-04
    • 2018-11-07
    • 1970-01-01
    相关资源
    最近更新 更多