[英]Convert Flutter stream from Firebase to ints
我有一個具有聊天功能的 Flutter 應用程序,其中聊天存儲在 Firebase 數據庫中。 我有一個BottomNavigationBar
,它有一個聊天圖標按鈕。 如果有任何未讀聊天,我會在此圖標上顯示一個徽章:
BottomNavigationBarItem(
icon: new Stack(
children: <Widget>[
ImageIcon(AssetImage('images/icons.png')),
_unreadCount != null && _unreadCount > 0 ? Positioned(
right: 0,
child: new Container(
padding: EdgeInsets.all(1),
decoration: new BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(6),
),
constraints: BoxConstraints(
minWidth: 12,
minHeight: 12,
),
child: new Text(
'$_unreadCount',
style: new TextStyle(
color: Colors.white,
fontSize: 8,
),
textAlign: TextAlign.center,
),
),
) : null
].where((c) => c != null).toList(),
),
title: Text('Chats', style: TextStyle(fontWeight: FontWeight.w500))
),
我使用返回Future<int>
的方法獲取_unreadCount
。 它將查詢聊天 firebase 數據庫並返回未讀聊天的數量:
Future<int> getUnreadCount() async {
bool isLoggedIn = await connection.isUserLoggedIn();
int count = 0;
if(isLoggedIn) {
int userId = await _getUserId();
final QuerySnapshot chatsQuerySnapshot =
await Firestore.instance.collection("chats")
.where("userIds", arrayContains: userId)
.getDocuments();
final List<DocumentSnapshot> documents = chatsQuerySnapshot.documents;
if(documents != null && documents.isNotEmpty) {
for (DocumentSnapshot chatsSnapshot in documents) {
if(chatsSnapshot['unread'] as bool) {
count++;
}
}
}
}
return count;
}
但是,因為這將返回Future
,所以只有在重新構建BottomNavigationBar
時(即當我單擊另一個選項卡時)並且調用Future
方法時,才會更新徽章。
我需要一種返回Stream
的方法,但我找不到任何按我想要的方式工作的樣本。 在我看來,流僅在返回數據集合/列表時使用,但我只想要一個int
。 我對反應式編程知之甚少,而且我是新手,但是如何以這種方式查詢 Firebase?
This is the exact use case of the map
function: simply wrap the relevant widget in your BottomNavigationBar
in a StreamBuilder
that takes a mapped version of your Firebase stream as an argument. 請參閱您可以在StreamBuilder
中使用的以下(未經測試的) Stream<int>
:
Firestore.instance.collection("chats")
.where("userIds", arrayContains: userId)
.snapshots()
.map((snapshot) {
return snapshot.documents.fold(0, (count, doc) {
return (doc['unread'] as bool) ? count + 1 : count;
});
});
使用 Dart 中為List
s/ Iterable
s 提供的眾多方法之一, fold
調用可能會更干凈,但我將把它留給你。
這是您可以為FutureBuilder
制作的Future<int>
,如評論中所述:
/// Returns the userId if the user is logged in, or null otherwise
Future<int> userIdWrapper() async {
final isLoggedIn = await connection.isUserLoggedIn();
return isLoggedIn ? await _getUserId() : null;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.