将Flatter流从Firebase转换为ints
我有一个带有聊天功能的Flitter应用程序,聊天记录存储在Firebase数据库中。我有一个将Flatter流从Firebase转换为ints,firebase,flutter,reactive-programming,Firebase,Flutter,Reactive Programming,我有一个带有聊天功能的Flitter应用程序,聊天记录存储在Firebase数据库中。我有一个BottomNavigationBar,它有一个用于聊天的图标按钮。如果有任何未读的聊天,我将在此图标上显示一个徽章: BottomNavigationBarItem( icon: new Stack( children: <Widget>[
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> 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
方法时,才会更新徽章
我需要一个返回
流的方法
,但是我找不到任何按照我想要的方式工作的示例。在我看来,流仅在返回数据集合/列表时使用,但我只需要一个int
。我对反应式编程知之甚少,而且我对它还不熟悉,但我如何以这种方式查询Firebase?这就是该函数的确切用例:只需将相关小部件包装在底部导航栏中的StreamBuilder
中,该小部件将Firebase流的映射版本作为参数。请参阅以下(未经测试的)流
,您可以在StreamBuilder
中使用这些流:
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
创建的未来
,如评论中所述:
/// 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;
}
///如果用户已登录,则返回userId,否则返回null
未来的userIdWrapper()异步{
final isLoggedIn=等待连接。isUserLoggedIn();
return isLoggedIn?wait_getUserId():null;
}
谢谢您的回答!看起来很有希望,但正如您所看到的,我有几个调用正在等待未来的值(如connection.isUserLoggedIn()
和\u getUserId())
。如何在返回流的方法中使用它们?虽然您可以使用RxDart提供的一些实用程序将数据保存在同一个流中,但最好将StreamBuilder
与我提供的流包装到FutureBuilder
中,然后使用Fu的构建方法中提供的结果tureBuilder
来构建StreamBuilder
。因此,您可以创建一个异步函数,该函数返回Future
,如果用户未登录,该函数将返回null,如果用户未登录,则返回userId的int。您可以提供一些示例代码吗?我不知道如何执行此操作..当然;我给出了一个您可以为future作为我答案的编辑。你知道如何使用FutureBuilder和StreamBuilder吗?