【问题标题】:Upload folder(s) on firebase - javascript在firebase上上传文件夹 - javascript
【发布时间】:2019-03-08 16:16:01
【问题描述】:

我们可以在 firebase 存储上上传空文件夹或仅上传包含许多文件的文件夹吗?

因为实际上我可以上传一个文件,但也可以上传多个文件,但我没有找到如何使用文件夹。

【问题讨论】:

    标签: javascript firebase firebase-storage


    【解决方案1】:

    无法一次性将整个文件夹上传到 Cloud Storage for Firebase。您必须上传文件夹中的各个文件。

    Cloud Storage for Firebase 中没有空文件夹的概念。文件夹仅因其中有文件而存在。

    另见:

    【讨论】:

    • 感谢您的回答。
    • 但是我们可以创建一种文件文件夹上传吗,例如,我们通过拖放检索文件夹(因为我使用拖放..),我们取文件夹的名称,以及其中的所有文件,我们只需使用文件夹名称在firebase存储中创建一个文件夹,然后通过多个文件上传将所有文件存储在firebase存储中的文件夹中。能不能用?? @FrankvanPuffelen
    • 我认为您不会在 JavaScript 中获得文件夹中的文件列表,因为这会带来安全风险。但是,如果用户丢弃了多个文件,您可以遍历这些文件,上传它们,包括重新创建部分文件夹结构。这是一个多步骤的用例,但绝对有可能。如果您在实施它时遇到问题,请准确显示您卡在哪一步。请参阅how to create a minimal, complete, verifiable example 以获得帮助的最佳机会。
    【解决方案2】:

    我建议您访问 Google Cloud(Firebase 项目也存在于 Google Cloud 中),并在那里检查您的存储分区。您将能够在那里看到上传文件夹选项,您可以使用该选项通过 GUI 上传文件夹。您可以根据需要拖放多个文件夹。

    【讨论】:

    • 太棒了!多谢了。是的,只需为您的 firebase 项目打开 Google Cloud 存储桶。效果很好!
    【解决方案3】:

    要以编程方式执行此操作,最好的解决方案是:

    (1) 递归获取要上传的文件夹中所有文件的列表

    (2) 使用 Promise.all 一次性上传所有文件

    这种方法之所以有效,是因为 Firebase 会为您创建缺少的存储路径

    (1) 和 (2) 的代码(用 TS 编写)如下

    递归获取文件列表

    import { Dirent, readdirSync } from 'fs'
    import path from 'path'
    import { IPath } from '../interfaces/i-path'
    import { escapeRegExp } from 'lodash'
    
    interface IDirent {
      dirent: Dirent
      path: string
    }
    
    const getAllFiles = (dir: string): IDirent[] => {
    
      const dirents: IDirent[] = readdirSync(dir, { withFileTypes: true }).map((dirent: Dirent) => ({ dirent, path: path.resolve(dir, dirent.name) }))
    
      return dirents.reduce((acc: IDirent[], dirent: IDirent) => {
        if (dirent.dirent.isDirectory()) return [...acc, ...getAllFiles(dirent.path)]
        if (dirent.dirent.isFile()) return [...acc, dirent]
        return acc
      }, [])
    }
    
    export const getAllFilesInFolder = (dir: string): IPath[] => {
    
      const regex = new RegExp(`^${escapeRegExp(dir)}`)
    
      return getAllFiles(dir).map((dirent: IDirent) => {
        let shortPosixPath: string = dirent.path.replace(regex, '')
        shortPosixPath = shortPosixPath.split(path.sep).join(path.posix.sep)
        if (shortPosixPath.startsWith(path.posix.sep)) shortPosixPath = shortPosixPath.substring(1)
        return { fullPath: dirent.path, shortPosixPath }
      })
    }
    

    一键上传所有文件

    import os from 'os'
    import { getAllFilesInFolder } from '../../utils/get-all-files-in-folder'
    import { IPath } from '../../interfaces/i-path'
    import admin from 'firebase-admin'
    import { getObjectPath } from '../../utils/string-utils'
    import path from 'path'
    import * as functions from 'firebase-functions'
    
    // the following code will live inside some function
    
    const storageBasePath = 'videos-out/test-videos/video-14/hls'
    
    const dir: string = '/temp/my-folder-to-upload'
    const files: IPath[] = getAllFilesInFolder(dir)
    
    // object.bucket is just a string and is the bucket you are uploading to - e.g. something.appspot.com
    const promises = files.map((file: IPath) => {
      const destination = `${storageBasePath}/${file.shortPosixPath}`
      return admin.storage().bucket(object.bucket).upload(file.fullPath, { destination })
    })
    
    Promise.all(promises).then(
      () => console.log('success')
    ).catch(
      () => console.log('failure')
    )
    

    最后,接口IPath很简单

    export interface IPath {
      fullPath: string
      shortPosixPath: string
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-08
      • 2021-04-27
      • 2017-05-17
      • 2016-03-11
      • 2018-04-26
      • 2012-01-14
      • 1970-01-01
      相关资源
      最近更新 更多