C#操作Firestore时如何更新指定字段且保留字段原数据类型
Firestore 布尔字段类型保留的切换更新问题
问题背景
下图为搭建的Firebase Firestore数据库结构:
当前已完成数据库连接,可获取目标文档ID,能够准确定位到Notes集合下的对应文档。遇到的问题为:需要将bool类型字段added在true、false之间切换,更新时不能修改文档内的其他数据,且要保留原有字段的数据类型(如createDate保持DateTime类型、added保持bool类型)。
已尝试的错误方案
方案1:全量Set覆盖
最初使用的参考代码如下:
DocumentReference docref = db.Collection("Notes").Document(notes[a].id); Dictionary<string, object> data = new Dictionary<string, object>() { { "added","true"}, { "createDate",notes[a].createDate.ToString()}, { "id",notes[a].id.ToString()}, { "localisation",notes[a].localisation.ToString()}, { "notes",notes[a].notes.ToString()}, { "title",notes[a].title.ToString()}, { "uid",notes[a].uid.ToString()}, }; DocumentSnapshot snap = await docref.GetSnapshotAsync(); if (snap.Exists) { await docref.SetAsync(data); }
该方案存在两个明确问题:
- 调用
SetAsync且未传合并参数时,会直接覆盖文档全部内容 - 所有字段都调用
ToString()方法写入,会将原本的DateTime、bool类型字段强制转为字符串类型,破坏原有数据结构
方案2:单字段Update传字符串值
后续尝试仅更新added字段的代码如下:
DocumentReference docref = db.Collection("Notes").Document(notes[a].id); Dictionary<string, object> data = new Dictionary<string, object>() { { "added","true"}, }; DocumentSnapshot snap = await docref.GetSnapshotAsync(); if (snap.Exists) { await docref.UpdateAsync(data); }
该方案仍不符合要求:传入的"true"是字符串类型值,会把Firestore中原本bool类型的added字段修改为字符串类型。
正确实现方法
问题根因
两次方案出错的核心原因有两个:
- 误用全量覆盖的
SetAsync方法,未使用仅更新指定字段的接口 - 写入
added字段时传入了带引号的字符串"true",而非C#原生布尔值,导致字段类型被篡改
实现要点
- 切换布尔值无需重写全文档,先读取快照中
added的原有布尔值,取反后更新即可 - 写入字段时直接传递对应C#原生类型值:布尔值传
true/false不加引号,DateTime值直接传DateTime类型对象,不要调用ToString()转换 - 调用
UpdateAsync方法仅更新指定字段,未在更新字典中声明的字段会完整保留原有值与数据类型
参考代码
DocumentReference docref = db.Collection("Notes").Document(notes[a].id); DocumentSnapshot snap = await docref.GetSnapshotAsync(); if (snap.Exists) { // 读取字段原有布尔值 bool currentAddedStatus = snap.GetValue<bool>("added"); // 构造更新数据,直接传入取反后的布尔值,不要加引号转为字符串 Dictionary<string, object> updatePayload = new Dictionary<string, object>() { { "added", !currentAddedStatus } }; // 执行单字段更新,其余字段不受影响 await docref.UpdateAsync(updatePayload); }
若不需要动态切换、仅需固定设置布尔值,只要保证传入值为C# bool类型即可,例如
{ "added", false }会直接写入布尔类型的false,不会修改字段原有类型。
内容的提问来源于stack exchange,提问作者Maciek
相关产品推荐
相关产品推荐

