我可以不使用Node.js管理员进行身份验证就写入Firestore吗

时间:2019-12-16 00:48:52

标签: node.js firebase google-cloud-firestore google-cloud-functions firebase-admin

我编写了一个云函数,该函数在上载到云存储后会调整图像的大小,然后返回上载图像的签名URL,但是当我随后尝试将该URL写入firestore时,我会得到 PERMISSION_DENIED:缺少权限或权限不足错误是否可以解决此问题,而无需更改Firestore规则以允许任何人进行读/写访问?

下面是代码:

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

import * as fs from "fs-extra";
import { tmpdir } from "os";
import { join, dirname } from "path";
import * as sharp from "sharp";

admin.initializeApp({
  credential: admin.credential.applicationDefault()
});

const gcs = admin.storage();
const db = admin.firestore();

export const generateThumbs = functions.storage
  .object()
  .onFinalize(async object => {
    const bucket = gcs.bucket(object.bucket);
    const filePath = object.name as string;
    const fileName = filePath.split("/").pop();
    const bucketDir = dirname(filePath);

    const workingDir = join(tmpdir(), "thumbs");
    const tmpFilePath = join(workingDir, "source.png");

    if (fileName?.includes("@") || !object.contentType?.includes("image")) {
      console.log("exists, returning false...");
      return false;
    }

    // Ensure thumbnail dir exists
    await fs.ensureDir(workingDir);

    // Download source file
    await bucket.file(filePath).download({
      destination: tmpFilePath
    });

    // Resize the images and define an array of upload promises
    const sizes = [64, 128, 320, 640];

    const uploadPromises = sizes.map(async size => {
      const imageName = fileName?.split(".")[0];
      const imageExt = fileName?.split(".")[1];
      const thumbName = `${imageName}@${size}.${imageExt}`;
      const thumbPath = join(workingDir, thumbName);

      //   Resize source images
      return sharp(tmpFilePath)
        .resize(size, size)
        .toFile(thumbPath)
        .then(outputInfo => {
          // Upload to GCS
          return bucket
            .upload(thumbPath, {
              destination: join(bucketDir, thumbName)
            })
            .then(async res => {
              return res[0]
                .getSignedUrl({
                  action: "read",
                  expires: "01-01-2040"
                })
                .then(signedUrlRes => {
                  console.log(`url: ${signedUrlRes[0]}`);

                  // const docRef = db
                  //   .collection("/cities")
                  //   .doc(imageName?.split("_")[0] as string);

                  // return db.runTransaction(t => {
                  //   t.set(docRef, {
                  //     imageUrl: signedUrlRes[0]
                  //   });
                  //   return Promise.resolve();
                  // });

                  return db
                    .collection("/cities")
                    .doc(imageName?.split("_")[0] as string)
                    .set({
                      imageUrl: signedUrlRes[0]
                    })
                    .then(res => console.log("written"))
                    .catch(e => {
                      console.log("Firebase write error");
                      console.log(e);
                      throw Error(e);
                    });
                })
                .catch(e => {
                  console.log(e);
                  throw Error(e);
                });
            });
        });
    });

    // Run upload operations
    await Promise.all(uploadPromises).catch(e => {
      console.log(e);
      throw Error(e.message);
    });

    return fs.remove(workingDir).catch(e => {
      console.log(e);
      throw Error(e.message);
    });
  });

1 个答案:

答案 0 :(得分:0)

更改了 admin.initializeApp()
admin.initializeApp({
  credential: admin.credential.applicationDefault()
}); 

admin.initializeApp(functions.config().firebase);