Typescript操作Firestore报错:DocumentReference无update属性
问题原因
两个报错均由Firebase JS SDK v9+ 模块化API和旧版v8链式写法混用导致:
- v9及以上版本采用模块化设计,
update、set、collection等操作都是独立导出的顶层函数,不再挂载到DocumentReference、Firestore等实例对象上。 - 你代码里写的
doc.ref.update()、Firestore.collection()都是v8及更早版本的链式调用写法,TS做静态类型检查时,自然会识别不到v9对应实例类型上不存在的属性。 - 你在node_modules中看到的
update方法,要么是v8兼容层的定义,要么是内部未对外暴露的实现,不属于v9模块化API对外暴露的类型定义范围,不能直接调用。
解决方案
统一使用v9模块化API写法即可,步骤如下:
- 先从
firebase/firestore导入需要的模块化方法:
import { initializeFirestore, collection, query, where, getDocs, updateDoc } from "firebase/firestore"; // 替换成你自己项目里Firebase App实例的导入路径 import { Firebase } from "./your-firebase-init-path";
- 修正更新逻辑,调用顶层
updateDoc方法传入文档引用和更新数据,同时修正forEach中async逻辑不等待的问题:
const Firestore = initializeFirestore(Firebase); const vendorsRef = collection(Firestore, '/vendors'); const q = query(vendorsRef, where("uuid", "==", vendorUuid)) const querySnapshot = await getDocs(q); // 收集所有更新任务,统一等待执行完成 const updateTasks: Promise<void>[] = []; querySnapshot.forEach((doc) => { // 模块化写法:updateDoc(文档引用, 更新字段),替换原来的doc.ref.update() updateTasks.push(updateDoc(doc.ref, { deleted: '06-02-2022' })); }); // 等待所有软删除操作执行完毕,避免后续逻辑依赖删除结果时出现时序问题 await Promise.all(updateTasks);
如果你更习惯旧版v8的链式调用写法,可以引入v9的兼容层,将导入路径替换为firebase/firestore/compat,即可继续使用doc.ref.update()、Firestore.collection()这类旧写法,但模块化写法支持tree-shaking,能有效减少打包体积,更推荐使用。
注意不要混用模块化API和compat兼容层API,否则容易出现类型冲突或运行时异常。
内容的提问来源于stack exchange,提问作者Janelle Thorn Contreras
相关产品推荐
相关产品推荐

