【发布时间】:2019-03-08 16:16:01
【问题描述】:
我们可以在 firebase 存储上上传空文件夹或仅上传包含许多文件的文件夹吗?
因为实际上我可以上传一个文件,但也可以上传多个文件,但我没有找到如何使用文件夹。
【问题讨论】:
标签: javascript firebase firebase-storage
我们可以在 firebase 存储上上传空文件夹或仅上传包含许多文件的文件夹吗?
因为实际上我可以上传一个文件,但也可以上传多个文件,但我没有找到如何使用文件夹。
【问题讨论】:
标签: javascript firebase firebase-storage
无法一次性将整个文件夹上传到 Cloud Storage for Firebase。您必须上传文件夹中的各个文件。
Cloud Storage for Firebase 中没有空文件夹的概念。文件夹仅因其中有文件而存在。
另见:
【讨论】:
我建议您访问 Google Cloud(Firebase 项目也存在于 Google Cloud 中),并在那里检查您的存储分区。您将能够在那里看到上传文件夹选项,您可以使用该选项通过 GUI 上传文件夹。您可以根据需要拖放多个文件夹。
【讨论】:
要以编程方式执行此操作,最好的解决方案是:
(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
}
【讨论】: