首页 > 解决方案 > 从 firebase 存储读取并使用 firebase 函数写入 firestore

问题描述

我试过这个打字稿代码

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";

import serviceAccount from "/Users/300041370/Downloads/serviceKey.json";

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});

const buckObj = functions.storage.bucket("myBucket").object();
export const onWikiWrite = buckObj.onFinalize(async (object) => {
  const filePath = object.name ?? "test.json";
  const bucket = admin.storage().bucket("myBucket");

  bucket.file(filePath).download().then((data) => {
    const contents = data[0];
  data = {"key": "value"};
const doc = admin.firestore().collection("myCollection").doc();
doc.set(data);
  });
});

但这给了我以下错误

"status":{"code":7,"message":"权限不足,无法(重新)配置触发器(存储桶 myBucket 的权限被拒绝)。请授予存储桶编辑者角色的所有者权限,然后重试。

我在这里问过这个问题,但它作为这个问题的重复而被关闭。它基本上storage.bucket("myBucket")是说,不支持该功能,我将不得不改为match将此操作限制为此特定存储桶/文件夹中的文件。因此,我尝试了这个

const buckObj = functions.storage.object();
export const onWikiWrite = buckObj.onFinalize(async (object) => {
  if (object.name.match(/myBucket\//)) {
    const fileBucket = object.bucket;
    const filePath = object.name;
    const bucket = admin.storage().bucket(fileBucket);
    bucket.file(filePath).download().then((data) => {
      const contents = data[0];
      const doc = admin.firestore().collection("myCollection").doc();
      const data = {content: contents}
      doc.set(data);
    });
  }
});

我仍然面临同样的问题。我将在这里重复一遍:

"status":{"code":7,"message":"权限不足,无法(重新)配置触发器(存储桶 myBucket 的权限被拒绝)。请授予存储桶编辑者角色的所有者权限,然后重试。

标签: firebasegoogle-cloud-functionsgoogle-cloud-storagefirebase-storage

解决方案


由于 Cloud Functions 的 Firebase SDK 版本 1.0,firebase-admin应在 Cloud Functions 运行时内不带任何参数进行初始化。

以下应该可以工作(我已经删除了对 的检查filePath):

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();

export const onWikiWrite = functions.storage
  .object()
  .onFinalize(async (object) => {
    const fileBucket = object.bucket;
    const filePath = object.name;
    const bucket = admin.storage().bucket(fileBucket);
    return bucket
      .file(filePath)
      .download()
      .then((data) => {
        const contents = data[0];
        return admin
          .firestore()
          .collection('myCollection')
          .add({ content: contents });
      });
  });

请注意,我们返回异步 Firebase 方法返回的承诺链。在执行异步处理的云函数(也称为“后台函数”)中,当所有异步处理完成时返回 JavaScript 承诺是关键。

我们也使用add()方法而不是做doc().set()


最后,在检查 的值时filePath,请注意 Cloud Storage 中实际上没有文件夹或子目录的概念(请参阅此答案)。


推荐阅读