在通过云功能将文件添加到云存储后,什么可能导致 Firebase 控制台显示“等待"图标(旋转蓝色循环图标)? [英] What might cause the firebase console to show the 'waiting' icon (spinning blue loop icon) after adding a file via cloud functions to cloud storage?

查看:34
本文介绍了在通过云功能将文件添加到云存储后,什么可能导致 Firebase 控制台显示“等待"图标(旋转蓝色循环图标)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我现在可以使用谷歌云功能将文件存储在云存储中,上传文件后,我可以在 firebase 控制台中看到它的名称,即当您通过各种文件夹向下钻取时,在存储区域内.

So, I can now use a google cloud function to store a file in cloud storage, and after uploading a file I can see it's name in the firebase console, i.e. within the Storage area as you drill down via the various folders.

我也可以查询和检索+查看文件,所以看起来它存储正常.

I can also query and retrieve+view the file, so it seems like it's stored ok.

但是,我不明白为什么我无法在 firebase 控制台中单击该文件并查看它的预览.

However, I don't understand why I cannot click on the file in the firebase console and see a preview of it.

我唯一的猜测是上传文件的云函数没有释放文件句柄或其他东西,因此 firebase 控制台认为它已被锁定.

My only wild guess is that the cloud function to upload the file didn't release a file handle or something, and so firebase console thinks it's locked.

firebase 控制台中显示的文件属性似乎正确.

The file attributes shown in firebase console seem correct.

上传文件的云函数代码如下:

The cloud function code to upload the file is as follows:

const imageBuffer = Buffer.from(arr[1], 'base64');
const bufferStream = new stream.PassThrough();
bufferStream.end(imageBuffer);

const fullPath = `${filePath}/${data.filename}`

console.log('saving to fullPath', fullPath)

const myFile = bucket.file(fullPath)

bufferStream.pipe(myFile.createWriteStream({
       metadata: {
         contentType: mime
       },
       public: true,
       validation: "md5"
    }))
     .on('error', function (err) {
      console.log('error from image upload', err);
    })
    .on('finish', function () {
       console.log('!!!!!! finished')
     })

其中 arr[1] 是字符串的 base64 部分,即从开头删除 mime 类型的东西,因此 arr[1] 是作为 base64 的纯文件数据.

where arr[1] is the base64 portion of a string, i.e. remove the mime type stuff from the beginning so arr[1] is the pure file data as base64.

所以,除了 firebase 控制台无法查看文件之外,基本上一切似乎都运行良好,除非我重新部署应用程序,即 npm run build &&firebase部署&&npm start,然后似乎 (?) 释放了锁,我可以在 firebase 控制台中查看用于 firebase 存储的图像预览.

So, basically everything seems to be working perfectly except the firebase console can't view the file, unless I do an app redeploy, i.e. npm run build && firebase deploy && npm start, and then it seems (?) to free up the lock and I can view the image preview in the firebase console for firebase storage.

推荐答案

重新审视这个问题,而不是使用会增加不必要开销的 PassThrough 流,您可以直接将缓冲区写入流本身.

Revisiting this, rather than use the PassThrough stream which is adding unnecessary overhead, you could write your buffer to the stream itself directly.

const imageBuffer = Buffer.from(arr[1], 'base64');

const fullPath = `${filePath}/${data.filename}`

console.log('saving to fullPath', fullPath)

const myFile = bucket.file(fullPath)

const fileWriteStream = myFile
  .createWriteStream({
    metadata: {
      contentType: mime
    },
    public: true,
    validation: "md5"
  })
  .on('error', function (err) {
    console.log('error from image upload', err);
  })
  .on('finish', function () {
    console.log('!!!!!! finished')
  });
  
fileWriteStream.end(imageBuffer);

重写为基于 Promise 的实用函数:

Rewritten as a promise-based utility function:

import { File } from "@google-cloud/storage";
import { storage } from "firebase-admin";

async function uploadDataURI(dataURI: string, options: { bucket?: string, filename: string, filepath: string, public?: boolean, contentType?: string }): Promise<File> {
  const { bucket, filename, filepath, public, contentType } = options;

  const [, mediaType, data] = dataURI.split(/[;,]/);

  let contentTypeFromURI: string, buffer: Buffer;
  if (mediaType.endsWith(";base64")) {
    contentTypeFromURI = mediaType.slice(0,-7);
    buffer = Buffer.from(data, "base64");
  } else {
    contentTypeFromURI = mediaType;
    buffer = Buffer.from(decodeURIComponent(data));
  }

  const storageRef = storage()
    .bucket(bucket)
    .file(`${filepath}/${filename}`);
    
  return new Promise((resolve, reject) => {
    try {
      const fileWriteStream = storageRef
        .createWriteStream({
          metadata: {
            contentType: contentType || contentTypeFromURI || undefined // coerce falsy values to undefined
          },
          public,
          validation: "md5"
        })
        .on('error', reject)
        .on('finish', () => resolve(storageRef));
      
      fileWriteStream.end(buffer);
    } catch (err) {
      reject(err);
    }
  }); 
}

这篇关于在通过云功能将文件添加到云存储后,什么可能导致 Firebase 控制台显示“等待"图标(旋转蓝色循环图标)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆