借助Firebase Cloud Functions实现每日更新3条共享随机食谱方案咨询
实现方案:每日固定随机食谱(Firebase Cloud Functions + Flutter)
完全可以通过Firebase Cloud Functions实现需求,且Blaze套餐是必要前提(免费Spark套餐不支持定时触发器),但你的使用场景(每日一次函数调用、200条数据)成本极低,Firebase免费额度足以覆盖,不用担心费用问题。
核心思路
通过定时Cloud Function每日自动从Firestore食谱集合中随机挑选3条,存入一个专门的「每日推荐」文档;Flutter端直接读取该文档,确保所有用户看到的内容一致,且24小时自动更新。
具体步骤
1. Firestore数据结构准备
新增一个集合dailyFeaturedRecipes,里面只保留一个名为current的文档,字段定义:
recipes: 数组类型,存储选中的3条食谱的完整数据或ID(根据业务需求选择)updatedAt: 时间戳类型,记录文档最后更新时间
2. 编写定时Cloud Function
使用Node.js编写函数,配置每日定时触发器,逻辑如下:
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); // 每日定时更新推荐食谱(可指定时区) exports.updateDailyFeaturedRecipes = functions.pubsub.schedule('every 24 hours') .timeZone('Asia/Shanghai') // 替换为你的目标时区 .onRun(async (context) => { const recipesCol = admin.firestore().collection('recipes'); const allRecipesSnapshot = await recipesCol.get(); if (allRecipesSnapshot.empty) { functions.logger.error("No recipes found in Firestore"); return null; } // 获取所有食谱ID列表 const recipeIds = allRecipesSnapshot.docs.map(doc => doc.id); // 生成3个不重复的随机索引 const selectedIds = []; while (selectedIds.length < 3) { const randomIdx = Math.floor(Math.random() * recipeIds.length); const targetId = recipeIds[randomIdx]; if (!selectedIds.includes(targetId)) { selectedIds.push(targetId); } } // 批量获取选中的食谱数据 const selectedRecipes = await Promise.all( selectedIds.map(id => recipesCol.doc(id).get()) ).then(docs => docs.map(doc => ({ id: doc.id, ...doc.data() }))); // 更新每日推荐文档 await admin.firestore().collection('dailyFeaturedRecipes').doc('current').set({ recipes: selectedRecipes, updatedAt: admin.firestore.FieldValue.serverTimestamp() }); functions.logger.info("Daily featured recipes updated successfully"); return null; });
3. Flutter端读取数据
在Flutter中直接读取dailyFeaturedRecipes/current文档,获取数据后展示即可:
// 示例代码 final firestore = FirebaseFirestore.instance; Future<List<Recipe>> getDailyFeaturedRecipes() async { final doc = await firestore.collection('dailyFeaturedRecipes').doc('current').get(); if (!doc.exists) { // 处理首次未生成数据的情况(可手动触发一次函数或返回默认食谱) return []; } final data = doc.data()!; return (data['recipes'] as List).map((json) => Recipe.fromJson(json)).toList(); }
关键注意事项
- Blaze套餐要求:定时Cloud Functions仅在Blaze套餐下可用,但你的使用场景调用频率极低(每日1次),数据处理量小,Firebase的免费额度(每月5万次函数调用、1GB数据传输)完全覆盖,实际产生的费用几乎为0。
- 时区设置:务必在定时触发器中指定正确时区,避免更新时间不符合预期。
- 首次数据初始化:部署函数后,可手动在Firebase控制台触发一次函数,生成第一组推荐数据,避免用户首次打开App时无数据。
内容的提问来源于stack exchange,提问作者NisiCH
相关产品推荐
相关产品推荐

