我正在使用從 github 下載的教程構建一個聊天應用程式,但由于它是由 firestore 制作的,并且人們建議用戶使用 firebase RTDB,所以現在我正在轉換所有相關代碼,我遇到的一個問題如下:
這是我的代碼:
static Stream<List<User>> getUsers() {
return usersReference.onValue.listen((event){
final data = Map<String, dynamic>.from(event.snapshot.value);
final UserList = User.fromJson(data).toList();
return UserList;
});
}
我想為以下小部件使用 getUsers() 方法:
Widget build(BuildContext context) =>
Scaffold(
backgroundColor: Colors.blue,
body: SafeArea(
child: StreamBuilder<List<User>>(
stream: FirebaseApi.getUsers(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
if (snapshot.hasError) {
print(snapshot.error);
return buildText('Something Went Wrong Try later');
} else {
final users = snapshot.data;
if (users.isEmpty) {
return buildText('No Users Found');
} else
return Column(
children: [
ChatHeaderWidget(users: users),
ChatBodyWidget(users: users)
],
);
}
}
},
),
),
);
這是為 firestore 制作的原始代碼,我想用我的代碼替換它:
static Stream<List<User>> getUsers() => FirebaseFirestore.instance
.collection('users')
.orderBy(UserField.lastMessageTime, descending: true)
.snapshots()
.transform(Utils.transformer(User.fromJson));
所以這里出現了讓我哭的錯誤:
A value of type 'StreamSubscription<DatabaseEvent>' can't be returned from the method 'getUsers' because it has a return type of 'Stream<List<User>>'.
如果你有任何關于如何使用 firebase rtdb 的線索,請幫助我,非常感謝,順便說一句,為什么有這么多的 firestore 聊天應用程式教程,這些教程會比 rtdb 更貴。
非常感謝提前并保持安全!
經過多次實驗更新,我不確定以下是否是正確的解決方案:
Stream<List<User>> getUsers() {
getUserStream = usersReference.onValue.listen((event){
final data = Map<String, dynamic>.from(event.snapshot.value);
final userList = User.fromJson(data);
return userList;
});
}
user.fromJson 是以下代碼:
static User fromJson(Map<String, dynamic> json) => User(
idUser: json['idUser'],
name: json['name'],
urlAvatar: json['urlAvatar'],
lastMessageTime: Utils.toDateTime(json['lastMessageTime']),
);
所以這意味著我將資料從 Json 傳輸到 List,我理解正確嗎?感謝您的解釋,這個社區非常友好,我只是一個軟體初學者,但 35 歲以上:)
在絕望的實驗后更新,因為上面回傳錯誤:
This function has a return type of 'Stream<List<User>>', but doesn't end with a return statement.
我嘗試了另一種使用另一個小部件的解決方案:
Widget build(BuildContext context) {
return FirebaseAnimatedList(
query: _usersReference.child("timestamp"),
sort: (a, b) => (b.key.compareTo(a.key)),
defaultChild: new CircularProgressIndicator(),
itemBuilder: (context, snapshot, animation, index) {
final data = Map<String, dynamic>.from(snapshot.value);
final List<User> users = data.entries.map((e) => e.value).toList();
return Column(
children: [
ChatHeaderWidget(users: users),
ChatBodyWidget(users: users)
],
);
});
}
所以根據我的理解能力差query: _usersReference.child("timestamp"),會給我一張地圖,我只需要轉換為一個串列ChatHeaderWidget(users: users),是否正確?
對不起,我的問題和日記很長,我現在無法測驗它,因為還有太多錯誤。
uj5u.com熱心網友回復:
Stream<List<User>> getUsers() {
getUserStream = usersReference.onValue.listen((event){
final data = Map<String, dynamic>.from(event.snapshot.value);
final userList = User.fromJson(data);
return userList;
});
}
這個方法沒有回傳值。usersReference.onValue 是一個流,你必須用它回傳。例如,您可以使用 Stream.map() 方法將流事件轉換為您可以在 StreamBuilder 中使用的用戶串列。
因此,一種可能的解決方案如下:
Stream<List<User>> getUsers() =>
FirebaseDatabase.instance.ref().onValue.map((event) =>
event.snapshot.children
.map((e) => User.fromJson(e.value as Map<String, dynamic>))
.toList());
我想象你的資料結構是這樣的:
"users": {
"userId1": { /* userData */ },
"userId2": { /* userData */ },
"userId3": { /* userData */ }
}
現在,您可以在 StreamBuilder 中接收實時資料庫更改。您有一個用戶串列,所以我認為您學習路徑的下一步是在螢屏上顯示這些用戶。如果要使用 Column 進行測驗,則必須生成它的所有子項。例如,您也可以在用戶串列上使用 map 方法。
Column(children: userList.map((user) => ListTile(title: Text(user.name))).toList())
或其他解決方案
Column(children: [
for (var user in users)
ListTile(title: Text(user.name))
])
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/395311.html
上一篇:即使收到更新的資料,FlutterListView.builder的UI也不會被getx更新
下一篇:如何僅在內部專案上保留邊距?
