React项目Firestore保存Map类型数据遇setDoc报错问题排查
问题解决:Firestore保存Map类型时提示“unsupported field value: a custom Map object”
错误原因
Firestore JavaScript SDK 不支持直接序列化原生JavaScript Map对象——虽然Firestore数据模型本身支持键值对类型(文档中提到的Map指的是这种键值对结构),但你传入的是原生Map实例,SDK无法识别并完成序列化,因此抛出错误。
解决方案
需要将原生Map转换为普通的JSON键值对对象(Plain Object)后,再传入Firestore。
方法1:保存前手动转换数据
在调用updateCreateSingleDocument方法前,对positions字段做转换:
// 假设待保存的用户数据是userData const userToSave = { ...userData, // 将Map转为普通键值对对象 positions: Object.fromEntries(userData.positions) }; // 调用保存方法 updateCreateSingleDocument<IUser>('users', userId, userToSave);
方法2:在保存方法内部自动处理
如果希望所有包含Map的类型都能自动适配,可以修改updateCreateSingleDocument方法,在传入setDoc前递归转换数据:
protected updateCreateSingleDocument = <T>( url: string, id: string, data: T ): Promise<T> => { return new Promise(async (resolve, reject) => { try { // 递归转换所有Map为普通对象 const transformMapToObject = (obj: any): any => { if (obj instanceof Map) { return Object.fromEntries(obj); } if (typeof obj === 'object' && obj !== null) { for (const key in obj) { obj[key] = transformMapToObject(obj[key]); } } return obj; }; const transformedData = transformMapToObject({...data}); const docRef = doc(collection(db, removeSpace(url)), id); await setDoc(docRef, transformedData as any, { merge: true, }); resolve(data) } catch (error) { reject(error) } }) }
额外说明
如果后续从Firestore读取数据时需要转回原生Map,可以用以下方式处理:
// 假设从Firestore获取的用户数据是fetchedUser const userWithMap = { ...fetchedUser, positions: new Map(Object.entries(fetchedUser.positions)) };
内容的提问来源于stack exchange,提问作者Alula48
相关产品推荐
相关产品推荐

