调整存储在firebase存储中的所有现有图像的大小,并通过api调用将新调整大小的图像url更新到数据库



我需要调整存储在firebase存储中的新图像和现有图像的大小。对于新图像,我启用了firebase的resize图像扩展。对于现有的图像,我如何调整图像的大小,并获得新调整大小的图像url更新回数据库通过api。

这是我的firebase函数从数据库中获取现有的图像url。我的问题是如何调整图像的大小,并获得新的图像url?

const functions = require("firebase-function ");Const axios =require("axios");

异步函数getalbum () {

const endpoint = "https://api.mydomain.com/graphql";
const headers = {
"content-type": "application/json",
};
const graphqlQuery = {
"query": `query Albums {
albums {
id
album_cover
}
}`
};
functions.logger.info("Call API");
const response = await axios({
url: endpoint,
method: 'post',
headers: headers,
data: graphqlQuery
});
if(response.errors) {
functions.logger.info("API ERROR : ", response.errors) // errors if any
} else {
return response.data.data.albums;
}
}
exports.manualGenerateResizedImage = functions.https.onRequest(async () => {
const albums = await getAlbums();
functions.logger.info("No. of Album : ", albums.length);
});

我想下面Renaud Tarnec的回答一定会对你有所帮助。

如果你看一下"调整图像大小"扩展时,您将看到作为扩展基础的Cloud Function是由onFinalize事件触发的,这意味着:

新对象(或现有对象的新一代)是桶中创建成功。这包括复制或重写已存在的对象。

因此,如果不重写/重新生成现有的图像,扩展将不会被触发。

然而,你可以很容易地编写自己的云函数,做同样的事情,但被触发,例如,通过调用一个特定的URL (HTTPS云函数)或通过在临时的Firestore集合中创建一个新文档(后台触发CF)。

这个云函数将执行以下步骤:

  1. 获取bucket的所有文件,参见谷歌云存储Node.js客户端API。此方法返回GetFilesResponse对象,它是一个文件实例数组。
  2. 通过循环遍历数组,对于每个文件,检查文件是否有桶中相应的调整大小的图像(取决于您的方式)配置扩展后,调整大小的图像可能会在特定的文件夹)
  3. 如果文件没有相应的调整大小的图像,则执行此文件的扩展云功能的业务逻辑相同。

有一个官方的云函数示例,它展示了如何创建一个云存储触发的Firebase函数,它将从上传的图像中创建大小调整的缩略图,并将它们上传到数据库URL,(参见index.js文件的最后几行)

注意:如果你有很多文件要处理,你应该批处理,因为有9分钟的限制为云功能执行。此外,根据要处理的图像数量,您可能需要增加超时值和/或Cloud Function分配的内存,请参阅https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation

以防有人需要。这是我如何调整现有图像的大小。

const functions = require("firebase-functions");
const axios = require("axios");
const { Storage } = require("@google-cloud/storage");
const storage = new Storage();
// Don't forget to replace with your bucket name
const bucket = storage.bucket("projectid.appspot.com");
async function getAlbums() {
const endpoint = "https://api.mydomain.com/graphql";
const headers = {
"content-type": "application/json",
};
const graphqlQuery = {
query: `query Albums {
albums {
id
album_cover
}
}`,
};
const response = await axios({
url: endpoint,
method: "post",
headers: headers,
data: graphqlQuery,
});
if (response.errors) {
functions.logger.error("API ERROR : ", response.errors); // errors 
if any
} else {
return response.data.data.albums;
}
}
function getFileName(url) {
var decodeURI = decodeURIComponent(url);
var index = decodeURI.lastIndexOf("/") + 1;
var filenameWithParam = decodeURI.substr(index);
index = filenameWithParam.lastIndexOf("?");
var filename = filenameWithParam.substr(0, index);
return filename;
}
function getFileNameFromFirestore(url) {
var index = url.lastIndexOf("/") + 1;
var filename = url.substr(index);
return filename;
}
const triggerBucketEvent = async () => {
bucket.getFiles(
{
prefix: "images/albums", // you can add a path prefix
autoPaginate: false,
},
async (err, files) => {
if (err) {
functions.logger.error(err);
return;
}
const albums = await getAlbums();
await Promise.all(
files.map((file) => {
var fileName = getFileNameFromFirestore(file.name);
var result = albums.find((obj) => {
return getFileName(obj.album_cover) === fileName;
});
if (result) {
var file_ext = fileName.substr(
(Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1
);
var newFileName = result.id + "." + file_ext;
// Copy each file on thumbs directory with the different name
file.copy("images/albums/" + newFileName);
} else {
functions.logger.info(file.name, " not found in album list!");
}
})
);
}
);
};
exports.manualGenerateResizedImage = functions.https.onRequest(async () => {
await triggerBucketEvent();
});

最新更新