调用document.update方法后文档无更新问题求助
问题场景
我是零基础初学者,正在修读大学入门级数据处理课程,当前任务是开发简易数据库应用,支持两个核心功能:
- 用户添加电影条目
- 将指定电影标记为「已观看」状态
我实现的标记已观看函数仅接收一个参数:数据库中的电影集合,集合内每个文档仅包含电影名称、已观看状态两个字段,函数预期逻辑为:提示用户输入电影名称,随后将匹配到的对应电影标记为已观看。
故障现象
代码最后一行的update方法执行后没有产生任何效果,始终无法定位原因。在update语句后添加打印命令测试,发现文档完全没有变化;甚至尝试同时更新电影名称字段,也没有任何改动。
涉及的源码如下:
watch(collection) async { print('Name of the movie?'); var name = stdin.readLineSync(); var terms = Query(filter: ValueFilter({'name': name})); var results = await collection.search(query: terms); var documents = results.snapshots; for (var i = 0; i < documents.length; i++) { var data = documents[i].data; var document = documents[i].document; document.update(data: {'name': data['name'], 'watched': true}); } }
问题根因
三个问题会导致该故障:
- 未等待异步操作执行:
document.update是异步方法,返回Future对象,调用时不加await关键字,程序不会等待更新操作落库就会继续向后执行,很可能更新请求还没发送到数据库,函数就已经运行结束,自然看不到数据变化。 - 查询匹配逻辑存在漏洞:
stdin.readLineSync()读取到的用户输入可能首尾带有空格、换行符残留,和数据库中存储的电影名无法精确匹配,导致查询返回的snapshots是空数组,循环根本不会执行,更新逻辑从头到尾没触发。 - 快照对象不支持直接写入:多数数据库SDK返回的查询快照是查询时刻的数据只读副本,不是和数据库绑定的可变引用,直接调用快照对象的
update方法不会把改动同步到持久化存储。
修正代码
watch(collection) async { print('Name of the movie?'); // 读取输入后去除首尾空白字符,避免无效输入导致匹配失败 var name = stdin.readLineSync()?.trim(); if (name == null || name.isEmpty) { print('Please enter a valid movie name'); return; } var terms = Query(filter: ValueFilter({'name': name})); var results = await collection.search(query: terms); var documents = results.snapshots; if (documents.isEmpty) { print('No matching movie found in database'); return; } for (var i = 0; i < documents.length; i++) { var data = documents[i].data; // 通过文档ID从集合获取真实可写的文档引用 var docRef = collection.doc(documents[i].document.id); // 加await等待更新完成后再进入下一次循环 await docRef.update(data: { 'name': data['name'], 'watched': true }); } print('Successfully marked the movie as watched'); }
内容的提问来源于stack exchange,提问作者Riku
相关产品推荐
相关产品推荐

