我正在努力实现以下目标。但是,我不知道因为我是firebase的初学者。
直到此,我已经完成了。现在,我需要调整上传的图像大小。
为此,我正在尝试使用Cloud Functions,每当新条目添加到firestore数据库时,我都会调用Cloud fountion,它可以访问图像的下载URL,使用此下载URL,我需要调整大小图片。请帮忙。
如果有更好的方法可以实现这一点,请告诉我。 (我知道应该有:P)
修改1
感谢 Frank 的回复。
我有以下云功能,将为每个帖子插入调用。我从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告诉我如何进行图像大小调整操作。
答案 0 :(得分:1)
您可以让Cloud Storage触发云功能来调整图像大小,而不是从Cloud Firestore获取URL。在GitHub上有一个很好的例子。
Firebase SDK for Cloud Functions Quickstart - Cloud Storage trigger
答案 1 :(得分:1)
我也在firestore中创建了一个文档,我将其用作网站的后端。我也想调整图像大小(适合卡片)并将URL写回firestore。我发现了一种解决方案,它使用与将图像上传到存储所触发的标准示例不同的模式。
基本上,我将图像上传到存储,然后将URL写入我的应用页面中的Firestore。然后,我使用Firestore的onCreate()触发器触发该函数。
该功能抓取' image_name'来自firestore并使用它来获取存储中的文件引用。接下来,它遵循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
})
});
答案 2 :(得分:0)
我也需要实现这一目标,但是对我而言,使用Cloud Storage触发器不是一个合适的解决方案,因为我不想调整所有内容的大小。
我的情况是,用户将上传许多图像,但是他们选择了其中一个作为缩略图。我将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
})
})
答案 3 :(得分:0)
当用户创建或更新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);
});