[英]Firestore Cloud Function: Getting “ReferenceError: firebase is not defined”
[英]Firebase Cloud Function to resize image on firestore create
我正在努力实现以下目标。 但是,我不知道因为我是firebase的初学者。
直到这个,我已经完成了。 现在,我需要调整上传的图像大小。
为此,我正在尝试使用云功能,每当新条目添加到firestore数据库时,我都会调用Cloud fountion,它可以访问图像的下载URL,使用此下载URL,我需要调整图像大小。 请帮忙。
如果有更好的方法来实现这一点,请告诉我。 (我知道应该有:P)
编辑1
谢谢弗兰克的回复。
我有下面的云功能,将为每个帖子插入调用。 我从eventSnapshot获取图像的下载URL。 我需要调整该位置的图像大小。 请帮忙。
exports.resizeImage = functions.firestore
.document('posts/{postId}')
.onCreate(event => {
var eventSnapshot = event.data.data();
//In this eventSnapshot I am getting the document, and I can get the download URL from the document
});
我已经分析了创建缩略图的示例,但为此,我需要
存储对象,只有在更改存储对象时才会调用它。 但是,当在firestore中调用onWrite时,我需要创建缩略图。
exports.generateThumbnail = functions.storage.object().onChange((event) => {
// File and directory paths.
const filePath = event.data.name;
});
请通过检测firestore中的onWrite并使用downLoadURL告诉我如何进行图像大小调整操作。
您可以让Cloud Storage触发云功能来调整图像大小,而不是从Cloud Firestore获取URL。 在GitHub上有一个很好的例子。
我也在firestore中创建了一个文档,我将其用作网站的后端。 我也想调整图像大小(适合卡片)并将URL写回firestore。 我发现了一种解决方案,它使用与将图像上传到存储所触发的标准示例不同的模式。
基本上,我将图像上传到存储,然后在我的应用页面中将URL写入Firestore。 然后我使用Firestore的onCreate()触发器触发该函数。
该函数从firestore中获取“image_name”并使用它来获取存储中的文件引用。 接下来,它遵循generate-thumbnail firebase示例的模式。
然后诀窍是抓住signedUrl并将其写回img_src中的firestore。
如果其他人发现这有用:
const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')({keyFilename: 'service-key.json'});
const spawn = require('child-process-promise').spawn;
const path = require('path');
const os = require('os');
const fs = require('fs');
exports.createCard = functions.firestore
.document('work_cards/{cardID}')
.onCreate((snap, context) => {
const newCardData = snap.data()
const bucket = gcs.bucket('your-project-id.appspot.com')
const file = bucket.file(newCardData.image_name)
const tempFilePath = path.join(os.tmpdir(), file.name);
const thumbFileName = `thumb_${file.name}`;
const thumbFilePath = bucket.file(thumbFileName)
const contentType = file.contentType;
const metadata = {
contentType: contentType
};
return bucket.file(file.name).download({
destination: tempFilePath,
})
.then(() => {
return spawn('convert', [tempFilePath, '-thumbnail', '250x250', tempFilePath]);
})
.then(() => {
return bucket.upload(tempFilePath, {
destination: thumbFilePath,
metadata: metadata,
})
})
.then(() => {
return thumbFilePath.getSignedUrl({
action: 'read',
expires: '03-09-2491'
})
})
.then(signedUrls => {
const img_src = signedUrls[0]
return snap.ref.set({img_src}, {merge: true});
})
.then(() => {
bucket.file(file.name).delete()
fs.unlinkSync(tempFilePath)
return
})
});
我也需要实现这一点,但对我来说,使用云存储触发器不是一个合适的解决方案,因为我不想调整所有内容。
我的情况是用户会上传一些图像,但他们选择了一个作为缩略图。 我修改了Birch的代码作为可调用函数,其中文件引用数据被传递给它
exports.generateThumbnail = functions.https.onCall((data, context) => {
const file = bucket.file(`/designs/${context.auth.uid}/${data.design}/${data.image}`)
const tempFilePath = path.join(os.tmpdir(), `${data.image}`);
const thumbFileName = `thumb_${data.image}`;
const thumbFilePath = bucket.file(`/designs/${context.auth.uid}/${data.design}/${thumbFileName}`);
return bucket.file(file.name).download({
destination: tempFilePath,
})
.then(() => {
return spawn('convert', [tempFilePath, '-trim','-resize', '190', tempFilePath]);
})
.then(() => {
return bucket.upload(tempFilePath, {
destination: thumbFilePath,
})
})
.then(() => {
fs.unlinkSync(tempFilePath)
return
})
})
当我们的用户创建或更新firestore对象时,我通过生成和设置缩略图来实现。
import * as admin from "firebase-admin";
const mkdirp = require("mkdirp-promise");
import { spawn } from "child-process-promise";
import * as path from "path";
import * as os from "os";
import * as fs from "fs";
export default async function resizeImage(
filePath: string,
size: string
): Promise<string> {
// File and directory paths.
const fileDir = path.dirname(filePath);
const fileName = path.basename(filePath);
const thumbFilePath = path.normalize(
path.join(fileDir, `thumb_${size}_${fileName}`)
);
const tempLocalFile = path.join(os.tmpdir(), filePath);
const tempLocalDir = path.dirname(tempLocalFile);
const tempLocalThumbFile = path.join(os.tmpdir(), thumbFilePath);
// Cloud Storage files.
const bucket = admin.storage().bucket();
const file = bucket.file(filePath);
const thumbFile = bucket.file(thumbFilePath);
const metadata = {
contentType: null
// To enable Client-side caching you can set the Cache-Control headers here. Uncomment below.
// 'Cache-Control': 'public,max-age=3600',
};
await file.getMetadata().then(data => {
if (data && data[0] && data[0]["contentType"]) {
metadata["contentType"] = data[0]["contentType"];
}
});
// Create the temp directory where the storage file will be downloaded.
await mkdirp(tempLocalDir);
// Download file from bucket.
await file.download({ destination: tempLocalFile });
console.log("The file has been downloaded to", tempLocalFile);
// Generate a thumbnail using ImageMagick.
await spawn(
"convert",
[
tempLocalFile,
"-auto-orient",
"-thumbnail",
`${size}>`,
tempLocalThumbFile
],
{ capture: ["stdout", "stderr"] }
);
console.log("Thumbnail created at", tempLocalThumbFile);
// Uploading the Thumbnail.
await bucket.upload(tempLocalThumbFile, {
destination: thumbFilePath,
metadata: metadata
});
console.log("Thumbnail uploaded to Storage at", thumbFilePath);
// Once the image has been uploaded delete the local files to free up disk space.
fs.unlinkSync(tempLocalFile);
fs.unlinkSync(tempLocalThumbFile);
return thumbFile
.getSignedUrl({
action: "read",
expires: "03-01-2500"
})
.then((urls: string[]) => urls[0]);
}
const functions = require("firebase-functions");
import { Change } from "firebase-functions";
import resizeImage from "./resizeImage";
async function resizeAvatar(snapshot: FirebaseFirestore.DocumentSnapshot) {
const data = snapshot.data();
const filePath = data && data.avatarPath;
if (!data || !filePath || data.avatarUrlSmall) {
return; // No avatar or already resized
}
const url = await resizeImage(filePath, "200x200");
await snapshot.ref.set({ avatarUrlSmall: url }, { merge: true });
}
exports.resizeAvatarOnCreate = functions.firestore
.document("users/{userID}")
.onCreate(async (snapshot: FirebaseFirestore.DocumentSnapshot) => {
await resizeAvatar(snapshot);
});
exports.resizeAvatarOnUpdate = functions.firestore
.document("users/{userID}")
.onUpdate(async (change: Change<FirebaseFirestore.DocumentSnapshot>) => {
await resizeAvatar(change.after);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.