Firebase 9.0.0中使用onSnapshot触发器获取数据更新前旧值的咨询
核心差异澄清
你提到的onUpdate触发器返回change对象可同时获取新旧数据的能力,是Firebase云函数的服务端特性,客户端Web SDK(包括v9及之后所有版本)的onSnapshot接口本身没有直接封装旧值返回的能力,需要通过本地缓存的方案自行实现。
具体实现方案
你可以本地维护一份当前监听集合的文档数据副本,每次onSnapshot触发时先从缓存中匹配对应文档的旧值,处理完业务逻辑后再更新缓存即可,修改后的参考代码如下:
import { getFirestore, collection, doc, onSnapshot, query } from 'firebase/firestore' import { initializeApp } from 'firebase/app'; const firebaseConfig = { apiKey: "", authDomain: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "" }; // Initialize Firebase const app = initializeApp(firebaseConfig); const db = getFirestore(app); // 本地缓存容器,存储当前cafes集合的所有文档最新数据 const cafeCache = new Map(); /** * 监听cafe集合所有文档变更的触发函数 */ export const onUpdate = async () => { const cafeCollection = collection(db, 'cafes'); const q = query(cafeCollection); onSnapshot(q, (snapshot) => { let changesArr = snapshot.docChanges(); if(changesArr.length == 1){ let changes = changesArr[0]; const docId = changes.doc.id; const newData = changes.doc.data(); console.log(changes.type); // 变更类型:added-新增 modified-修改 removed-删除 console.log(docId); // 被变更的文档id console.log('最新数据:', newData); // 仅修改类型的变更可以匹配到对应的旧值 if(changes.type === 'modified') { const oldData = cafeCache.get(docId); console.log('旧数据:', oldData); // 此处可写入你的新旧数据业务处理逻辑 } // 更新本地缓存:删除操作移除缓存项,新增/修改操作更新缓存为最新值 if(changes.type === 'removed') { cafeCache.delete(docId); } else { cafeCache.set(docId, {...newData}); } } }) }
注意事项
- 首次执行
onSnapshot时会拉取当前集合的全量初始数据,此时所有变更的type都是added,会直接写入缓存,后续触发的修改操作就可以正常获取旧值 - 如果仅需要监听单个文档的变更,不需要用Map存储全集合数据,只需要维护单个缓存对象即可
- 如果需要对比新旧数据的字段差异,可以手动遍历两个对象的字段匹配,也可以引入第三方深对比工具实现
内容的提问来源于stack exchange,提问作者Ahmet Yazici Student
相关产品推荐
相关产品推荐

