我正在构建一个基于图像的食物日记,它可以根据一盘食物的图片自动对食物和营养进行人工智能分析。这在社交上非常适合分享。我们希望能够通过将图像、标题和描述添加到要共享的每顿饭菜的 Opengraph 标签中,在社交共享渠道中创建动态展开。对于 React 中内置的离子电容器应用程序来说,这是很困难的,因为它无法使用 Next.js 进行服务器端渲染。我在 Google Firebase 上托管我的后端,我该怎么做?
我做了很多研究才实现这个目标,所以想与 Stack Overflow 分享。
这是可能的,尽管很多消息来源说这是不可能的。步骤如下。
所以从高层次上来说,这非常简单,但我想分享一些问题。这是解决方案的更详细的分解和解释。
export const expressAppv2 = onRequest({ region: 'europe-west1'},expressApp);
// Middleware to serve static files
expressApp.use(express.static(path.join(__dirname, 'public')));
问题 1: 确保此静态路径映射到应用程序的“dist”目录。 “dist”是最新版本的 Ionic 使用 Vite 编译到的文件夹。这告诉应用程序在哪里查找index.html 文件。
expressApp.get('/p/:uId/:id', async (req, res) => {
const { uId, id } = req.params;
// Fetch user content from Firestore
const userMeal = await getUserMeal(uId, id);
// Read the index.html file from your dist directory
const indexHtml = fs.readFileSync('./dist/index.html', 'utf8');
// Use cheerio to parse and manipulate the HTML
const $ = cheerio.load(indexHtml);
// Update or add meta tags
$('title').text(userMeal.title);
$('meta[name="description"]').attr('content', userMeal.subTitle);
$('meta[property="og:title"]').attr('content', userMeal.title);
$('meta[property="og:description"]').attr('content', userMeal.subTitle);
$('meta[property="og:image"]').attr('content', userMeal.image);
$('meta[property="twitter:title"]').attr('content', userMeal.title);
$('meta[property="twitter:description"]').attr('content', userMeal.subTitle);
$('meta[property="twitter:image"]').attr('content', userMeal.image);
// If these meta tags don't exist, add them
if (!$('meta[property="og:type"]').length) {
$('head').append('<meta property="og:type" content="website" />');
}
if (!$('meta[name="twitter:card"]').length) {
$('head').append('<meta name="twitter:card" content="summary_large_image" />');
}
// Send the modified HTML
res.send($.html());
});
要运行此程序,您需要导入:
import * as fs from 'fs'; //For the file path
import * as cheerio from 'cheerio'; // For the HTML parsing
其关键要素是:
那就是云功能。还有另外几件事要做。
您需要通过添加此托管 json 来调整项目根目录中的 firebase.json 文件:
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/p/**",
"function": "expressAppv2"
},
{
"source": "**",
"destination": "/index.html"
}
]
},
此部分确保公共目录为“dist”,并设置“/p/**”上的任何页面来调用我们在 Cloud Functions 中创建的expressAppv2。
最后还有一个问题。
问题 2: Google Cloud Functions 无权访问主项目文件夹,它们只能访问项目中的函数文件夹。
因此,作为构建过程的一部分,我们需要将存储在项目根目录中的最新版本的index.html文件复制到functions文件夹中,以便Google Cloud Function可以访问它。
执行此操作所需的代码包含在函数目录中的 package.json 的构建脚本中。
{
"name": "functions",
"scripts": {
"build": "tsc && cp -R ../dist .",
...
},
}
这意味着“cp -R ../dist .”命令将在打字稿编译后运行,并将复制适当的构建文件。
这有效。
这最终并没有那么难,但是关于如何做到这一点的研究花了我好几个月的时间,因为我遇到了很多死胡同。