React.js中Firebase Firestore数字自增功能失效求助
Firestore字段自增功能失效问题修复
问题复现
在React项目中实现Firebase Firestore字段数值自增功能时,点击按钮触发自增逻辑无法正常运行,初始实现代码如下:
import firebase from 'firebase/compat/app'; import 'firebase/compat/auth'; import 'firebase/compat/firestore'; import { doc, updateDoc,} from "firebase/firestore"; import { db } from "../api/firebase_config"; // const mydb = firebase.firestore() import React from 'react' const Mcheck = () => { async function ResetCounter() { // userRef.update({ FieldToIncrease: increment }); const dataTable = doc(db, 'mycollection', 'Number'); const increment = firebase.firestore.FieldValue.increment(1); console.log(increment) // await updateDoc(dataTable, data) const res = await updateDoc(dataTable, { sale: increment }) } function checkClick() { ResetCounter() } return ( <div onClick={checkClick}><input type={"submit"} value='check' /></div> ) } export default Mcheck
对应错误日志截图:
根本原因
代码混用了Firebase v9 模块化SDK和compat兼容版两套互不兼容的API:
- 代码中使用的
db实例、doc()、updateDoc()都属于v9模块化SDK的导出 - 但自增标记
increment却取自compat兼容版的firebase.firestore.FieldValue
两套API生成的实例类型不匹配,就会触发参数类型错误,导致自增逻辑失败。
另外代码中调用async函数ResetCounter()时没有做异常捕获,操作报错时会直接抛出未捕获的Promise异常。
修复方案
二选一即可,禁止两套API交叉混用:
方案1:全量使用v9模块化API(官方推荐,打包体积更小)
移除不必要的compat包导入,从v9模块化包中直接导出increment方法使用,修复后代码:
import React from 'react' // 从v9模块化包中导入需要的方法,移除compat包的冗余导入 import { doc, updateDoc, increment } from "firebase/firestore"; import { db } from "../api/firebase_config"; const Mcheck = () => { async function ResetCounter() { const dataTable = doc(db, 'mycollection', 'Number'); // 直接调用模块化导出的increment方法 await updateDoc(dataTable, { sale: increment(1) }) } function checkClick() { // 补充异常捕获,避免未捕获Promise错误 ResetCounter().catch(err => console.error('自增操作执行失败:', err)) } return ( <div onClick={checkClick}><input type="submit" value='check' /></div> ) } export default Mcheck
方案2:全量使用compat兼容版API
如果习惯旧版命名空间式的写法,就把所有Firestore操作都替换为compat版的API,不要引用v9模块化的方法和实例:
import firebase from 'firebase/compat/app'; import 'firebase/compat/auth'; import 'firebase/compat/firestore'; import React from 'react' // 使用compat版初始化的db实例,不要引入v9模块化导出的db const db = firebase.firestore() const Mcheck = () => { async function ResetCounter() { // 用compat版的语法获取文档引用 const dataTable = db.doc('mycollection/Number'); const increment = firebase.firestore.FieldValue.increment(1); // 用文档引用自带的update方法 await dataTable.update({ sale: increment }) } function checkClick() { ResetCounter().catch(err => console.error('自增操作执行失败:', err)) } return ( <div onClick={checkClick}><input type="submit" value='check' /></div> ) } export default Mcheck
内容的提问来源于stack exchange,提问作者HimonHimu
相关产品推荐
相关产品推荐

