如何将图像复制到 Firebase 存储中的另一个参考路径?

How to copy an image over to another reference path in Firebase Storage?

在使用 react-native-firebase (v5) 的 react-native 应用程序 (v61.5) 中,我的图像路径如下所示:

/message-attachments/{session-id}

我已安排在一段时间后删除邮件,在此期间,所有已删除的邮件会话(其附件也存储在该会话 ID 引用中)也将被删除。

问题是,如果一个会话被存档,图像需要 moved/duplicated 从该消息附件引用到让我们说 /{user}/archived-attachments/{session-id} 所以它坚持计划的消息删除。

这个项目使用了 firebase 存储,我试图从复制的角度来实现这一点,因此不需要完全重新构建参考路径。根据 v5 react-native-firebase 文档,putFile() 只能采用 device 文件路径。但由于图像的来源是 firebase 中的另一个位置,因此似乎行不通。我唯一能想到的可能符合这些要求的是使用 .downloadFile('${firebase.storage.Native.DOCUMENT_DIRECTORY_PATH}/ok.jpeg') 并且在同一个 redux 操作中使用 putFile('${firebase.storage.Native.DOCUMENT_DIRECTORY_PATH}/ok.jpeg') 将它带到存储中的正确参考路径。

这似乎很老套,我更愿意避免将图像下载到用户设备上,还有其他方法吗?

下载并重新上传文件不好。从理论上讲,文件可能会变大,下载几兆大的文件然后重新上传是一个糟糕的解决方案。

相反,您可以创建一个云函数来执行移动 (copy/delete) 操作。

执行文件移动的 Firebase 函数(copy/delete)

const { Storage } = require('@google-cloud/storage');

exports.moveFile = functions.region(region).https.onCall(async (data, context) => {
  // Simple mechanism to secure the function call to logged in users.
  // There are other methods to secure cloud functions using IAM and
  // you should always specify rules to the storage buckets to allow users
  // view manage just their own files.

  const { auth } = context || {};
  const { uid } = auth || {};

  if (!uid) {
    throw 'Unauthenticated';
  }

  const srcBucketName = 'src-bucket';
  const destBucketName = 'dest-bucket'; // Can be the same as source bucket
  // Retrieve the file that the RN app passed to archive.
  // We should also check if it's a valid file.
  const { archiveFile } = data;
  const srcFilename = `path/to/currentFile/${archiveFile}`;
  const destFilename = `${uid}/archived-attachments/{session-id}/${srcFilename}`;

  const storage = new Storage();
  storage
    .bucket(srcBucketName)
    .file(srcFilename)
    .copy(storage.bucket(destBucketName).file(destFilename))
    .then(() => {
      console.log(
        `gs://${srcBucketName}/${srcFilename} copied to gs://${destBucketName}/${destFilename}.`
      );
      storage
        .bucket(srcBucketName)
        .delete()
        .then(() => {
          // Done moving file
          return res.status(200);
        })
        .catch(err => {
          console.error('DELETE ERROR:', err);
        });
    })
    .catch(err => {
      console.error('COPY ERROR:', err);
    });
});

使用@react-native-firebase/functions

在React native中调用函数
import firebase from '@react-native-firebase/app';
import '@react-native-firebase/functions';

firebase.app().functions(region).httpsCallable('moveFile')({
  archiveFile: 'some-file.txt'
}).then(() => {
  // Done moving file
}).catch(error => {
  // Handle error
});