是否可以复制 Firebase 存储上的现有文件而无需再次上传?
我需要它来设置我的应用程序的已发布/工作版本。
Firebase Storage API 中没有方法可以为您已上传的文件创建副本。
但是 Firebase Storage 构建在 Google Cloud Storage 之上,这意味着您也可以使用后者的 API。看起来
gsutil cp
就是您要找的。来自文档:
命令允许您在本地文件系统和云之间复制数据、在云内复制数据以及在云存储提供商之间复制数据。gsutil cp
请记住,
gsutil
拥有对您的存储桶的完全访问权限。因此,它应该在您完全信任的设备上运行(例如服务器或您自己的开发机器)。
这是我为我的项目最终采用的方法。
虽然它涵盖了更广泛的案例并将文件夹
fromFolder
下的所有文件复制到toFolder
,但它可以轻松地应用于问题中的案例(仅复制可以通过分隔符=“/”的文件 - 请参阅文档了解更多详情)
const {Storage} = require('@google-cloud/storage');
module.exports = class StorageManager{
constructor() {
this.storage = new Storage();
this.bucket = this.storage.bucket(<bucket-name-here>)
}
listFiles(prefix, delimiter){
return this.bucket.getFiles({prefix, delimiter});
}
deleteFiles(prefix, delimiter){
return this.bucket.deleteFiles({prefix, delimiter, force: true});
}
copyFilesInFolder(fromFolder, toFolder){
return this.listFiles(fromFolder)
.then(([files]) => {
let promiseArray = files.map(file => {
let fileName = file.name
let destination = fileName.replace(fromFolder, toFolder)
console.log("fileName = ", fileName, ", destination = ", destination)
return file.copy(destination)
})
return Promise.all(promiseArray)
})
}
}
我需要复制 Google Cloud Storage 中的文件夹(包括其所有后代)。这是 @vir-us 提出的简化的 NodeJS 解决方案。
import type { Bucket } from '@google-cloud/storage';
/** Copy Cloud Storage resources from one folder to another. */
export const copyStorageFiles = async (input: {
bucket: Bucket;
fromFolder: string;
toFolder: string;
logger?: Console['info'];
}) => {
const { bucket, fromFolder, toFolder, logger = console.info } = input;
const [files] = await bucket.getFiles({ prefix: fromFolder });
const promiseArray = files.map((file) => {
const destination = file.name.replace(fromFolder, toFolder);
logger("fileName = ", file.name, ", destination = ", destination);
return file.copy(destination);
});
return Promise.all(promiseArray);
};
Firebase 存储客户端支持在同一存储桶内复制文件:
await bucketFileRef.copy('new-path/to/file');
可以通过 @google-cloud/storage 直接访问。
firebase-admin
包,应该在函数后端使用,引用@google-cloud/storage
并且可以以类似的方式使用。
完整示例:
import { getStorage } from 'firebase-admin/storage';
const firebaseApp = initializeApp({
storageBucket: 'YOUR-BUCKET-PATH',
});
const main = async() => {
const bucket = getStorage(firebaseApp).bucket();
const bucketFileRefToCopy = bucket.file('path/file-to-copy');
// COPY
await bucketFileRefToCopy.copy('new-path/to/file');
};
main();