连接两个节点的Flatter firebase_数据库
通常,您可以使用javascript中的映射函数来更新返回的数据。我似乎找不到一种方法在Dart流中实现这一点 范例 我正在用Flatter firebase_数据库尝试这个连接两个节点的Flatter firebase_数据库,firebase,plugins,firebase-realtime-database,dart,flutter,Firebase,Plugins,Firebase Realtime Database,Dart,Flutter,通常,您可以使用javascript中的映射函数来更新返回的数据。我似乎找不到一种方法在Dart流中实现这一点 范例 我正在用Flatter firebase_数据库尝试这个 var _fireFollower =FirebaseDatabase.instance.reference() .child('followers/' + auth.currentUser.uid); _fireFollower.onValue.map((snap){ print(snap.
var _fireFollower =FirebaseDatabase.instance.reference()
.child('followers/' + auth.currentUser.uid);
_fireFollower.onValue.map((snap){
print(snap.snapshot.key);
});
然而,map函数从未被调用,因此当它从Firebase获取时,我无法加入任何其他数据
最后,我尝试使用的是FirebaseAnimatedList,因此,如果我不进行映射,如何传递查询
new FirebaseAnimatedList(
query: _fireFollower,
sort: (a, b) => b.key.compareTo(a.key),
padding: new EdgeInsets.all(8.0),
reverse: false,
itemBuilder: (_, DataSnapshot snapshot,
Animation<double> animation) {
return new Activity(
snapshot: snapshot, animation: animation);
},
),
新建FirebaseAnimatedList(
查询:_fireFollower,
排序:(a,b)=>b.key.compareTo(a.key),
填充:新边缘设置。全部(8.0),
反面:错,
itemBuilder:(),
动画(动画){
返回新活动(
快照:快照,动画:动画);
},
),
在flatter中,数据库参考。onValue
是一个流
,因此您必须调用它并在收听完毕后取消您的流订阅。如果只想获取一个值事件,则应调用one()
以获取表示快照值的Future
。当它完成时,您将拥有快照
Future.wait([fb.child('media/123').once(), fb.child('user/123').once()])
.then((snapshots) => print("Snapshots are ${snapshots[0]} ${snapshots[1]}"));
如果您在async
函数中执行此操作,则会更简单,因为您只需调用wait
即可获得once()的结果
我想这是@collin jackson建议的解决方案,这是我的代码
return new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Flexible(
child: new FirebaseAnimatedList(
query: FirebaseDatabase.instance
.reference()
.child('followers/${auth.currentUser.uid}'),
sort: (a, b) => b.key.compareTo(a.key),
padding: new EdgeInsets.all(8.0),
reverse: false,
itemBuilder: (_, DataSnapshot followerSnap,
Animation<double> animation) {
return new FutureBuilder<DataSnapshot>(
future: FirebaseDatabase.instance
.reference()
.child('users/${followerSnap.key}')
.once(),
builder: (BuildContext context,
AsyncSnapshot<DataSnapshot> userSnap) {
switch (userSnap.connectionState) {
case ConnectionState.none:
return new Text('Loading...');
case ConnectionState.waiting:
return new Text('Awaiting result...');
default:
if (userSnap.hasError)
return new Text(
'Error: ${userSnap.error}');
else
return new User(snapshot: userSnap.data, animation: animation);
}
},
);
},
),
),
]);
返回新列(
mainAxisAlignment:mainAxisAlignment.start,
儿童:[
新柔性(
子级:新的FirebaseAnimatedList(
查询:FirebaseDatabase.instance
.reference()
.child('followers/${auth.currentUser.uid}'),
排序:(a,b)=>b.key.compareTo(a.key),
填充:新边缘设置。全部(8.0),
反面:错,
itemBuilder:(u,DataSnapshot followerSnap,
动画(动画){
返回新的FutureBuilder(
未来:FirebaseDatabase.instance
.reference()
.child('users/${followerSnap.key}')
.once(),
生成器:(BuildContext上下文,
异步快照(用户快照){
开关(userSnap.connectionState){
案例连接状态。无:
返回新文本('加载…');
案例连接状态。正在等待:
返回新文本('等待结果…');
违约:
if(userSnap.hasError)
返回新文本(
'错误:${userSnap.Error}';
其他的
返回新用户(快照:userSnap.data,动画:动画);
}
},
);
},
),
),
]);
面向用户的类
@override
class User extends StatelessWidget {
User({this.snapshot, this.animation});
final DataSnapshot snapshot;
final Animation animation;
Widget build(BuildContext context) {
return new SizeTransition(
sizeFactor: new CurvedAnimation(parent: animation, curve: Curves.easeOut),
axisAlignment: 0.0,
child: new Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
margin: const EdgeInsets.only(right: 16.0),
child: snapshot.value['photoURl'] == null
? new CircleAvatar()
: new CircleAvatar(
backgroundImage: new NetworkImage(snapshot.value['photoURl']),
),
),
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(snapshot.value['displayName'],
style: Theme.of(context).textTheme.subhead),
],
),
],
),
),
);
}
}
@覆盖
类用户扩展无状态小部件{
用户({this.snapshot,this.animation});
最终数据快照快照;
最终动画;
小部件构建(构建上下文){
返回新的SizeTransition(
sizeFactor:新曲线动画(父对象:动画,曲线:Curves.easeOut),
axisAlignment:0.0,
子容器:新容器(
边距:常数边集。对称(垂直:10.0),
孩子:新的一排(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
新容器(
边距:仅限常量边集(右:16.0),
子项:快照。值['photoURl']==null
?新CircleAvatar()
:新CircleAvatar(
背景图像:新的网络图像(snapshot.value['photoURl']),
),
),
新专栏(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
新文本(snapshot.value['displayName'],
风格:Theme.of(context.textTheme.subhead),
],
),
],
),
),
);
}
}
Dart和Flift对我来说都是新手,但我认为firebase_数据库的插件有问题。我在github中为插件添加了更多内容。在我看来,我应该能够通过使用映射函数操纵流onValue
。更新了如何使用FirebaseAnimatedList的问题@collin Jacksony您可以使用FutureBuilder读取所需数据,并确保在构建列表时数据可用。只需使用常规ListVIEW,如果不需要它,在数据更改时自动更新。或者,您可以使用FutureBuilder让各个listview项执行更多查询。@为什么要返回new FutureBuilder
,而不是简单地返回卡片?另外,FutureBuilder DataSnapshot和FirebaseAnimatedList DataSnapshot有什么区别?在读取数据库内容时,需要使用FutureBuilder
或StreamBuilder
,因为这些值不同步可用AsyncSnapshot
被FutureBuilder
和StreamBuilder
用于异步提供值,它可以包装一个DataSnapshot
,它表示数据库项的键和值。这是一个很好的答案,但是我会使用StreamBuilder
和onValue
而不是FutureBuilder
和 return new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Flexible(
child: new FirebaseAnimatedList(
query: FirebaseDatabase.instance
.reference()
.child('followers/${auth.currentUser.uid}'),
sort: (a, b) => b.key.compareTo(a.key),
padding: new EdgeInsets.all(8.0),
reverse: false,
itemBuilder: (_, DataSnapshot followerSnap,
Animation<double> animation) {
return new FutureBuilder<DataSnapshot>(
future: FirebaseDatabase.instance
.reference()
.child('users/${followerSnap.key}')
.once(),
builder: (BuildContext context,
AsyncSnapshot<DataSnapshot> userSnap) {
switch (userSnap.connectionState) {
case ConnectionState.none:
return new Text('Loading...');
case ConnectionState.waiting:
return new Text('Awaiting result...');
default:
if (userSnap.hasError)
return new Text(
'Error: ${userSnap.error}');
else
return new User(snapshot: userSnap.data, animation: animation);
}
},
);
},
),
),
]);
@override
class User extends StatelessWidget {
User({this.snapshot, this.animation});
final DataSnapshot snapshot;
final Animation animation;
Widget build(BuildContext context) {
return new SizeTransition(
sizeFactor: new CurvedAnimation(parent: animation, curve: Curves.easeOut),
axisAlignment: 0.0,
child: new Container(
margin: const EdgeInsets.symmetric(vertical: 10.0),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
margin: const EdgeInsets.only(right: 16.0),
child: snapshot.value['photoURl'] == null
? new CircleAvatar()
: new CircleAvatar(
backgroundImage: new NetworkImage(snapshot.value['photoURl']),
),
),
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(snapshot.value['displayName'],
style: Theme.of(context).textTheme.subhead),
],
),
],
),
),
);
}
}