StreamBuilder在 Flutter 中使用Firestore 读取文档中的更改时,我如何收费?
每次我收听是否有任何变化或不乘以用户数量或使用任何不同的定价时,我都会收费吗?
我试图在流构建器中设置值,但是当我想使用 setState 函数设置值时,出现此错误。
在构建期间调用 setState() 或 markNeedsBuild()。
这是我的截图
int countRecent = 0;
...
return StreamBuilder<Object>(
stream: Data(uid: user.uid).getTrips,
builder: (context, snapshot) {
dynamic items = snapshot.data;
setState(() => countRecent = items.length);
}
...
Text(
"$countRecent",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900,
fontSize: 43,
letterSpacing: 0.2,
fontFamily: "VarelaRound",
),
),
Run Code Online (Sandbox Code Playgroud)
基本上,我想要的是每次文档更改(或者更确切地说该文档的长度)时更新此变量。
你有什么想法?
我们正在创建用户的编辑数据页面,因此文本字段已经充满了用户数据,用户可以更改并保存它。问题是,当我开始在文本字段中输入字符时,光标会丢失,每个字符我输入(从设备键盘输入),光标移到第一个字符...并且如果我删除带有初始值的控制器,它可以正常工作,但是我的文本字段无法填充用户数据。
代码示例:
child: StreamBuilder<String>(
stream: _bloc.myStream,
builder: (context, snap) => TextField(
decoration: InputDecoration(
hintText: 'example',
labelText: 'Name',
errorText: snap.error,
),
onChanged: _bloc.updateMyStream,
controller: TextEditingController(text: snap.data),
),
),
Run Code Online (Sandbox Code Playgroud) 我想要一个包含来自 Stream 的项目的 ListView。当然,List 的内容应该反映 Stream 中的变化。由于我的设计师怪癖,我希望列表中的项目由分隔符分隔。
只是想知道,使用分隔符创建 ListView 并对 Stream 更改做出反应的正确方法是什么。
body: StreamBuilder(
stream: someStream,
builder: (ctx, snapshot) {
return ListView.separated(
separatorBuilder: (context, index) => Divider(color: Colors.black),
itemCount: ***whatsHere***?,
itemBuilder: (BuildContext ctx, int index) {
...
Run Code Online (Sandbox Code Playgroud)
希望我错过了什么。由于以某种方式获取源流长度的想法至少看起来很奇怪,因为流的异步性质。StatefullWidget 使用流订阅(和 setState 调用)似乎是可行的,但是 StreamBuilder 的发明目的完全相同,不是吗?
我目前正在构建一个在 Google 地图上显示标记的应用程序。标记的位置是从 Firestore 数据库中提取的。目前,我正在成功检索并显示所有标记。但是,我需要根据数据库中的布尔值更新每个标记的图标。
这是我当前显示标记的方式。
我在主构建中创建地图:
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: mapToggle
? GoogleMap(
onMapCreated: onMapCreated,
compassEnabled: false,
polylines: route,
initialCameraPosition: CameraPosition(
target: LatLng(currentLocation.latitude,
currentLocation.longitude),
zoom: 12),
markers: markers,
)
: Center(
child: Text('Loading... Please wait...',
style: TextStyle(fontSize: 20.0)),
)),
Run Code Online (Sandbox Code Playgroud)
然后我在 initState 中调用这个函数来获取我的标记:
chargePoints() {
_database.collection('charge_points').getDocuments().then((docs) {
if (docs.documents.isNotEmpty) {
for (int i = 0; i < docs.documents.length; i++) {
initMarker(docs.documents[i].data, docs.documents[i].documentID);
}
}
});
Run Code Online (Sandbox Code Playgroud)
最后, initMarker 函数将每个标记添加到由 Google Map 实例获取的 Set 标记中:
void initMarker(chargePoint, documentID) {
var …Run Code Online (Sandbox Code Playgroud) google-maps google-maps-markers flutter google-cloud-firestore stream-builder
我有一个导航视图上有多个索引的应用程序,当我第一次加载该应用程序时,正如预期的那样,StreamBuilder 被调用两次。但是,当我导航到另一个索引并使用流构建器返回构建时,似乎正在调用流构建器来重新下载其中的所有项目。我担心如果这个循环运行的时间太长,这会消耗我所有的 firebase 数据。如何重构以阻止 StreamBuilder 在切换页面时被多次调用。请注意,当我切换并返回时,我什至保存了该索引的状态。
我的构建方法:
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection("posts/player/post")
.orderBy("time", descending: true)
.snapshots()
.take(2),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return const Text('Loading...');
final int highLightCount = snapshot.data.documents.length;
return new StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection("posts/player/post")
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData)
return new Text("There are no current posts");
return new ListView(
physics: const AlwaysScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: getPostItems(snapshot),
);
});
});
}
Run Code Online (Sandbox Code Playgroud)
当我切换它时,它正在调用几乎不间断地调用的 getPostItem(snaphot) ,我如何才能阻止调用它并消耗我的数据,或者阻止 StreamBuilder …
GetPhotoUrlStream 提供存储在我的 Cloud Firebase FireStore 中的个人资料照片 (data['profilePhoto']) 的 Url 流。然后被网络图像用来显示个人资料照片(圆形头像)
class GetUserPhotoUrlStream extends StatelessWidget {
final String documentId; // This is your User UID
GetUserPhotoUrlStream(this.documentId);
@override
Widget build(BuildContext context) {
DocumentReference users = FirebaseFirestore.instance.collection('users').doc(documentId);
return StreamBuilder<DocumentSnapshot>(
stream: users.snapshots(),
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Image.asset('assets/images/NouserImage.png');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
Map<String, dynamic> data = snapshot.data.data();
return CircleAvatar(
maxRadius: 80,
backgroundColor: Colors.grey,
child: ClipOval(child: FadeInImage(placeholder: AssetImage('assets/images/NouserImage.png'),image: NetworkImage("${data['profilePhoto']}"),),),
);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
removeUserPhotoUrl …
我正在努力寻找一种在 Flutter 中以动态间隔时间定期发出流的方法。我不确定,这真的可能吗?一种解决方法可能是取消旧的定期流并使用新的时间间隔重新初始化它,但我的 asyncMap 定期流没有取消选项。我可以使用具有取消方法的stream.listen,但我特意需要asyncMap将Future事件转换为流。在这种情况下,我能做什么,请给我建议。
我的代码片段 -
int i = 0;
int getTimeDiffForPeriodicEvent() {
i++;
return (_timeDiffBetweenSensorCommands * commandList.length + 1) * i;
}
StreamBuilder(
stream: Stream.periodic(
Duration(seconds: maskBloc.getTimeDiffForPeriodicEvent()))
.asyncMap((_) async => maskBloc.getDataFromMask()),
builder: (context, snapshot) {
return Container();
},
);
Run Code Online (Sandbox Code Playgroud) 我有一个DefaultTabController有两个选项卡的工作正常。在我的第二个选项卡上,我最近添加了一个stream controller用于在每次值发生变化时更新屏幕上的值,这也可以正常工作,但如果我要快速向左移动到第一个选项卡,然后返回到第二个选项卡,则会出现以下错误。
Stream has already been listened to.
我有一个处置功能,但由于没有导航到另一个页面,它不会触发,因此它创建了许多流,我不希望它这样做。
下面的所有代码都是针对流控制器的,如果我注释掉所有这些代码,应用程序可以正常工作,不会出现错误,而且我还发现,如果我只注释掉,stream: stream_controller.stream,我也不会收到错误。
StreamController<int> stream_controller = StreamController<int>();
Run Code Online (Sandbox Code Playgroud)
@override
void dispose(){
super.dispose();
stream_controller.close();
}
Run Code Online (Sandbox Code Playgroud)
StreamBuilder(
initialData: 0,
stream: stream_controller.stream,
builder: (context, snapshot) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'#${snapshot.data}',
),
);
})
Run Code Online (Sandbox Code Playgroud)
stream_controller.sink.add(rank);
Run Code Online (Sandbox Code Playgroud) 我想在从 StreamBuilder 获取数据后显示一个警报对话框。我还有一个要渲染的 UI。目前,当我尝试在返回实际 UI 之前在方法内部构建对话框时,遇到这样的错误_loadUI。
在构建期间调用 setState() 或 markNeedsBuild()。
代码:
if (dataSnapshot.hasData) {
return dataSnapshot.data ? _loadUI(dataSnapshot.data) : _emptyView();
}
Run Code Online (Sandbox Code Playgroud) 我试图在到达流构建器的末尾后加载更多数据,每次到达末尾时,流构建器都会重新加载并弹回到开头,并且它不允许我向下滚动(保持重新加载并弹回到开头)顶端)。
我尝试的是一旦到达终点,增加火力的限制,但我不确定问题是什么..任何人都可以帮助我吗?
这是我想要做的示例代码
_onEndScroll(ScrollMetrics metrics) {
//loadToTrue();
setState(() {
documentLimit = documentLimit + 10;
});
}
StreamBuilder(
initialData: cache,
stream: FirebaseFirestore.instance
.collection("timeline")
.doc(widget.currentUser.id)
.collection('timelinePosts')
.orderBy('timestamp', descending: true)
.limit(documentLimit)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> streamSnapshot) {
items = streamSnapshot.data != null &&
streamSnapshot.data.docs != null
? streamSnapshot.data.docs
: [];
List<Post> posts =
items.map((doc) => Post.fromDocument(doc)).toList();
cache = streamSnapshot.data;
return !streamSnapshot.hasData ||
streamSnapshot.connectionState ==
ConnectionState.waiting
? Center(
child: CircularProgressIndicator(),
)
: NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
if (scrollNotification is ScrollEndNotification) {
_onEndScroll(scrollNotification.metrics);
} …Run Code Online (Sandbox Code Playgroud) flutter ×11
stream-builder ×11
dart ×7
firebase ×3
stream ×2
controller ×1
google-maps ×1
listview ×1
loops ×1
rxdart ×1
textfield ×1