Reputation: 111
Typically you can use a map function in javascript to update the data coming back. I can not seem to find a method to allow for this in Dart Streams.
Example https://firebase.googleblog.com/2013/10/queries-part-1-common-sql-queries.html
var fb = new Firebase("https://examples-sql-queries.firebaseio.com/");
fb.child('user/123').once('value', function(userSnap) {
fb.child('media/123').once('value', function(mediaSnap) {
// extend function: https://gist.github.com/katowulf/6598238
console.log( extend({}, userSnap.val(), mediaSnap.val()) );
});
});
I was trying this using the flutter firebase_database.
var _fireFollower =FirebaseDatabase.instance.reference()
.child('followers/' + auth.currentUser.uid);
_fireFollower.onValue.map((snap){
print(snap.snapshot.key);
});
However the map function never gets called so I cannot join any other data when it gets fetched from Firebase.
Also the end of this what I am trying to use is a FirebaseAnimatedList, so how can I pass a Query if I don't do a map??
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);
},
),
Upvotes: 2
Views: 2211
Reputation: 111
I think this is the suggested solution by @collin-jackson, here is my code...
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);
}
},
);
},
),
),
]);
Class for User
@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),
],
),
],
),
),
);
}
}
Upvotes: 0
Reputation: 116848
In Flutter, DatabaseReference.onValue
is a Stream
, so you have to call Stream.listen
on it and cancel your StreamSubscription
when you're done listening. If you just want to get one value event, you should instead call once()
to get a Future
representing the snapshot value. When it completes, you'll have your snapshot.
Future.wait([fb.child('media/123').once(), fb.child('user/123').once()])
.then((snapshots) => print("Snapshots are ${snapshots[0]} ${snapshots[1]}"));
This can be even simpler if you do it in an async
function because you can just call await
to get the result of once()
:
print("Snapshots are ${await ref1.once()} ${await ref2.once()}");
Upvotes: 1