我可以在没有 nodejs 管理员身份验证的情况下写入 firestore
Can I write to firestore without authentication with nodejs admin
我写了一个云函数,它在上传到云存储后调整图像大小,然后 returns 为上传的图像签名 URL 但是当我之后尝试写 URL对于 firestore,我收到 PERMISSION_DENIED:缺少或权限不足错误 。 有没有办法在不更改 firestore 规则以允许任何人 read/write 访问的情况下解决这个问题?
代码如下:
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);
});
});
从
更改为 admin.initializeApp()
admin.initializeApp({
credential: admin.credential.applicationDefault()
});
到
admin.initializeApp(functions.config().firebase);
我写了一个云函数,它在上传到云存储后调整图像大小,然后 returns 为上传的图像签名 URL 但是当我之后尝试写 URL对于 firestore,我收到 PERMISSION_DENIED:缺少或权限不足错误 。 有没有办法在不更改 firestore 规则以允许任何人 read/write 访问的情况下解决这个问题?
代码如下:
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);
});
});
从
更改为 admin.initializeApp()admin.initializeApp({
credential: admin.credential.applicationDefault()
});
到
admin.initializeApp(functions.config().firebase);