Flutter报NoSuchMethodError: '[]' was called on null且功能仅热重载后生效如何解决
问题根源
你遇到的问题完全是异步操作和状态更新时序不匹配导致的,热重载后正常是因为热重载会保留之前已经加载完成的状态变量,不会再走初始化的异步等待逻辑:
- 你在
initState中调用的_getId是异步方法,界面第一次渲染时,异步请求还没有完成,userDocument仍为初始的null值 - 你把Firestore查询用户数据的逻辑放在了
setState代码块内,但then回调的执行时机晚于setState触发的界面刷新,而且你在then里给userDocument赋值后,没有再次调用setState通知界面重新渲染,所以就算拿到了admin角色,界面也不会更新显示悬浮按钮 - 你之前的代码里应该有过在空的
userDocument上调用['role']的操作,所以才会抛出NoSuchMethodError: The method '[]' was called on null错误
修复方案
只需要修改_getId方法,确保异步数据全部获取完成后再调用setState触发界面刷新即可:
Future _getId() async { var test = await FirebaseAuth.instance.currentUser(); // 先拿到用户uid,不需要在这里setState userId = test.uid; print(userId); // await等待Firestore查询完成 var documentSnapshot = await Firestore.instance .collection('users') .document(userId) .get(); // 所有数据拿到后再调用setState更新状态,触发界面重绘 setState(() { userDocument = documentSnapshot.data['role']; }); }
你现有的checkIfAdmin逻辑不需要调整,修改后首次启动拿到admin角色就会自动显示悬浮按钮,也不会再出现空值调用错误。
可选优化
你可以进一步简化Visibility的判断逻辑,不需要单独写方法:
floatingActionButton: Visibility( visible: userDocument == 'admin', // 其余原有代码保持不变 )
内容的提问来源于stack exchange,提问作者Nikhil Karve
相关产品推荐
相关产品推荐

