簡體   English   中英

將 Flutter stream 從 Firebase 轉換為整數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM