我在 StreamProvider 中使用
FirebaseAuth.instance.idTokenChanges()
返回的 Stream,每次用户注册/登录/退出时更新整个底层 Widget-tree。
例如,当我更新 displayName 时,有没有办法手动向该 Stream 添加事件,以便 StreamBuidler 使用新用户数据(新 displayName)重建小部件树,以便在 UI 中显示更改?
我是否可以访问与流关联的控制器,以便我可以在其上调用
.sink.add()
?或者有什么别的办法吗?
我想出了一个解决方案:使用 StreamGroup 类将两个(或多个)流合并为一个。
重要,这是来自 Flutter async 包,而不是 dart async:
import 'dart:async'; //async await and all that...
import 'package:async/async.dart'; //this contains StreamGroup
...
static StreamController<User> _ctrl;
static Future<void> initCombinedStream() async {
//without the following line, I get this Error on hot restart: "Bad state: Stream has already been listened to."
//maybe that error could also be caused by other reasons
dispose();
_ctrl = StreamController<User>();
StreamGroup streamGroup = StreamGroup<User>();
await streamGroup
..add(_ctrl.stream) //I use this stream when I want to update user info from my code
..add(FirebaseAuth.instance.idTokenChanges()) //normal firebase stuff...
..close();
_combinedStream = streamGroup.stream;
}
///this is also called from the overridden dispose() method of the highest StatefulWidget in my app
static void dispose() {
if (_ctrl != null) _ctrl.close();
}
//called when updating displayName for example, otherwise that wouldn't update in the UI
static void updateUserStream() {
await FirebaseAuth.instance.currentUser.reload(); //no need to call this, this User object is already updated
_ctrl.add(FirebaseAuth.instance.currentUser);
}