Flutter执行Firestore删除操作时抛出Bad state报错问题
报错根因
删除Firestore文档后,你监听的单文档Stream会立即推送一次最新快照,此时被删除的文档对应的快照对象本身不为空(因此snapshot.hasData判断为true),但快照的exists属性为false,代表文档已经不存在。你现有代码没有校验文档是否存在,直接尝试读取login/password/url等字段,就会抛出cannot get a field on a DocumentSnapshotPlatform which does not exist的错误。这也是为什么删除操作本身执行成功,但还是会报构建错误的原因。
修复步骤
- 替换StreamBuilder的builder里的状态判断逻辑,增加文档存在性校验,修正后的判断代码如下:
builder: (context, snapshot) { // 加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 错误状态 if (snapshot.hasError) { return Center(child: Text('数据加载失败: ${snapshot.error}')); } // 核心校验:无数据/文档已被删除 if (!snapshot.hasData || snapshot.data!.exists == false) { // 这里可以根据业务需求返回:删除成功提示、空组件、或者直接pop回上一页 return const Center(child: Text('当前密码条目已删除')); } // 安全获取文档数据,后续所有字段读取都用这个变量 final docData = snapshot.data!.data()!; // 原来的页面布局逻辑从这里开始写 return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // ... 其他原有组件 // 把原来所有snapshot.data!['xxx']的写法替换成docData['xxx'] // 比如原来的snapshot.data!['login'] 改成 docData['login'] ], ), ); }
- 修正代码里的语法和逻辑错误:
- 读取password字段时使用了中文单引号
‘password’,替换为英文单引号'password' - 删除按钮的文档路径写法错误:
widget.password(appname)要和流监听的路径保持一致,改为widget.password['appName'],否则会找错要删除的文档 - ListView.builder的itemCount增加空安全校验,避免url字段缺失时报错:
itemCount: (docData['url'] as List?)?.length ?? 0
验证逻辑
修复后,点击删除按钮时,文档删除成功后Stream推送的已删除快照会被exists校验拦截,不会再执行读取不存在文档字段的逻辑,报错就会消失,同时可以正常展示删除后的提示内容。
内容的提问来源于stack exchange,提问作者bigman1234
相关产品推荐
相关产品推荐

