连接两个节点的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.

通常,您可以使用javascript中的映射函数来更新返回的数据。我似乎找不到一种方法在Dart流中实现这一点

范例

我正在用Flatter firebase_数据库尝试这个

  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),
              ],
            ),
          ],
        ),
      ),
    );
  }
}