Flutter:StreamBuilder 中的项目(使用 firebase 实时数据库)随机排序
Flutter: Items in StreamBuilder(Using firebase realtime database) are sorted randomly
我正在使用 Firebase 实时数据库创建一个简单的应用程序,用户可以在其中输入文本并将其添加到聊天列表中。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.indigo,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _firebaseRef = FirebaseDatabase().reference().child('chats');
TextEditingController _txtCtrl = TextEditingController();
@override
Widget build(BuildContext context) {
var comments = _firebaseRef.orderByChild('time').limitToLast(10);
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
children: <Widget>[
Container(
child: Row(children: <Widget>[
Expanded(child: TextField(controller: _txtCtrl)),
SizedBox(
width: 80,
child: OutlineButton(
child: Text("Add"),
onPressed: () {
sendMessage();
}))
])),
StreamBuilder(
stream: comments.onValue,
builder: (context, snap) {
if (snap.hasData &&
!snap.hasError &&
snap.data.snapshot.value != null) {
Map data = snap.data.snapshot.value;
List item = [];
data.forEach(
(index, data) => item.add({"key": index, ...data}));
return Expanded(
child: ListView.builder(
itemCount: item.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(item[index]['message']),
);
},
),
);
} else
return Center(child: Text("No data"));
},
),
],
),
),
),
);
}
sendMessage() {
_firebaseRef.push().set({
"message": _txtCtrl.text,
'time': DateTime.now().millisecondsSinceEpoch
});
}
}
它完美地存储和检索数据。但是当我尝试添加数据时,新项目被放置在列表中的随机点。
例如,在下图中,我放入列表的最后一项是 'Nine'。但它被放在了列表的中心:
我试过按时间戳对列表进行排序,但没有任何效果。
是什么导致了这个问题?我该如何解决?
这可能有效:
使用查询
Query comments = _firebaseRef.orderByChild('time').limitToLast(10);
当您调用 snap.data.snapshot.value;
时,快照中的数据( 是 有序的)将转换为未排序的 Map<String, Object>
。为了维持秩序,您需要改为收听 onChild...
。
请注意,FlutterFire 有一个方便的 firebase_list
library 可以为您处理 onChild...
的大部分繁重工作。
另见:
- Flutter sort Firebase snapshot by timestamp
我正在使用 Firebase 实时数据库创建一个简单的应用程序,用户可以在其中输入文本并将其添加到聊天列表中。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.indigo,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _firebaseRef = FirebaseDatabase().reference().child('chats');
TextEditingController _txtCtrl = TextEditingController();
@override
Widget build(BuildContext context) {
var comments = _firebaseRef.orderByChild('time').limitToLast(10);
return Scaffold(
body: Container(
child: SafeArea(
child: Column(
children: <Widget>[
Container(
child: Row(children: <Widget>[
Expanded(child: TextField(controller: _txtCtrl)),
SizedBox(
width: 80,
child: OutlineButton(
child: Text("Add"),
onPressed: () {
sendMessage();
}))
])),
StreamBuilder(
stream: comments.onValue,
builder: (context, snap) {
if (snap.hasData &&
!snap.hasError &&
snap.data.snapshot.value != null) {
Map data = snap.data.snapshot.value;
List item = [];
data.forEach(
(index, data) => item.add({"key": index, ...data}));
return Expanded(
child: ListView.builder(
itemCount: item.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(item[index]['message']),
);
},
),
);
} else
return Center(child: Text("No data"));
},
),
],
),
),
),
);
}
sendMessage() {
_firebaseRef.push().set({
"message": _txtCtrl.text,
'time': DateTime.now().millisecondsSinceEpoch
});
}
}
它完美地存储和检索数据。但是当我尝试添加数据时,新项目被放置在列表中的随机点。
例如,在下图中,我放入列表的最后一项是 'Nine'。但它被放在了列表的中心:
我试过按时间戳对列表进行排序,但没有任何效果。
是什么导致了这个问题?我该如何解决?
这可能有效:
使用查询
Query comments = _firebaseRef.orderByChild('time').limitToLast(10);
当您调用 snap.data.snapshot.value;
时,快照中的数据( 是 有序的)将转换为未排序的 Map<String, Object>
。为了维持秩序,您需要改为收听 onChild...
。
请注意,FlutterFire 有一个方便的 firebase_list
library 可以为您处理 onChild...
的大部分繁重工作。
另见:
- Flutter sort Firebase snapshot by timestamp