Flutter中Firestore.get().then外部取值及StreamBuilder异步报错问题
问题解决方案
第一个问题:.then()外部无法获取更新后的weightValue
这是因为Firestore的get()是异步操作,.then()里的代码会在未来数据返回后才执行,而外部的print(weightValue)是同步执行的——此时weightValue还没被更新,所以打印的还是初始值"start"。
解决方法:改用await(需在async函数内),让代码等待异步操作完成后再执行后续逻辑:
// 确保当前函数是async的 String weightValue = "start"; // 获取用户设置的重量格式 var value = await db.collection('UserSettings').doc(userID).get(); weightValue = value['weightFormat']; print(weightValue); // 此时就能拿到更新后的值
如果不能用await(比如在非async环境),就把所有依赖weightValue的逻辑放到.then()内部:
String weightValue = "start"; db.collection('UserSettings').doc(userID).get().then((value) { weightValue = value['weightFormat']; print(weightValue); // 这里写所有需要用weightValue的代码 });
第二个问题:StreamBuilder中使用async builder报错
StreamBuilder的builder要求同步返回Widget,而async函数返回的是Future<Widget>,类型不匹配,所以会报错。
解决方法:用FutureBuilder嵌套在StreamBuilder内部,专门处理获取重量设置的异步逻辑:
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasData) { // 嵌套FutureBuilder处理getWeightSettings的异步请求 return FutureBuilder<String>( future: getWeightSettings(userID, db), builder: (context, weightSnapshot) { if (weightSnapshot.hasData) { String weightValue = weightSnapshot.data!; // 这里返回你需要渲染的Widget,比如显示重量格式 return Text("当前重量格式:$weightValue"); } else if (weightSnapshot.hasError) { return Text("加载重量格式失败"); } // 加载中的占位UI return CircularProgressIndicator(); }, ); } // Stream数据加载中的占位UI return CircularProgressIndicator(); }
这样既符合StreamBuilder的同步要求,又能正确获取异步的重量设置值。
内容的提问来源于stack exchange,提问作者Ten Digit Grid
相关产品推荐
相关产品推荐

