firebase - 按时间顺序显示

标签 firebase flutter dart google-cloud-firestore

使用 Dart/Flutter 连接到 Firebase 时,我的消息按时间顺序显示有一些问题。在 ListView 和查询 Firebase 时尝试反向顺序无济于事。
使用 Firebase Cloud Firestore 作为后端。我删除了firebase中的集合,将反向属性添加到数据检索和ListView中,但问题仍然存在。
我在 Firebase 中的数据库结构如下:

  • 收藏:留言/
  • 文件/
  • 字段(字符串:文本,字符串:发件人)

  • 我可能需要设置一个整数属性和字段,以按消息出现的顺序显示消息,但不知道该怎么做。
    以下是问题的屏幕截图和屏幕代码。
    1、2、3、4应按时间顺序出现。
    chronological issue flashchat
    final _firestore = Firestore.instance;
    FirebaseUser loggedInUser;
    
    class ChatScreen extends StatefulWidget {
      static const String id = 'chat_screen';
    
      @override
      _ChatScreenState createState() => _ChatScreenState();
    }
    
    class _ChatScreenState extends State<ChatScreen> {
      final messageTextController = TextEditingController();
      final _auth = FirebaseAuth.instance;
    
      String messageText;
    
      @override
      void initState() {
        super.initState();
        getCurrentUser();
        //retrieve the user credentials when screen is initialized
      }
    
      void getCurrentUser() async {
        try {
          final user = await _auth.currentUser();
          // if somebody is logged in this will display to the current user
          if (user != null) {
            //if we do have a signed in user
            loggedInUser = user;
            //save the [logged in] user to the loggedInUser variable
          }
        } catch (e) {
          print(e);
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            leading: null,
            actions: <Widget>[
              IconButton(
                  icon: Icon(Icons.close),
                  onPressed: () {
                    //Implement logout functionality
                    _auth.signOut();
                    //sign user out
                    Navigator.pop(context);
                  }),
            ],
            title: Text('⚡️Chat'),
            backgroundColor: Colors.lightBlueAccent,
          ),
          body: SafeArea(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                MessagesStream(),
                Container(
                  decoration: kMessageContainerDecoration,
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      Expanded(
                        child: TextField(
                          controller: messageTextController,
                          onChanged: (value) {
                            messageText = value;
                            //store the entry value of the text entry field as the variable messageText
                          },
                          decoration: kMessageTextFieldDecoration,
                        ),
                      ),
                      FlatButton(
                        onPressed: () {
                          messageTextController.clear();
                          //clear the text field on button press
                          _firestore.collection('messages').add({
                            'text': messageText,
                            'sender': loggedInUser.email,
                          });
                          //log the information and values according to those established within Firebase
                          //retrieved from database collection and fields established in Firebase
                        },
                        child: Text(
                          'Send',
                          style: kSendButtonTextStyle,
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class MessagesStream extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return StreamBuilder<QuerySnapshot>(
          //StreamBuilder establishes the Stream of data pushed from Firebase console
          //QuerySnapshot is the data type requested from the firebase console --> Querying a snapshot of the data housed in Firebase
    
          stream: _firestore.collection('messages').snapshots(),
          //the source of the stream should consist of the messages collection. Snapshots() performs the queries of the location to determine if there is anything new to push
    
          builder: (context, snapshot) {
            //build the stream to consist of the context and the snapshot query of the stream
    
            if (!snapshot.hasData) {
              //if the snapshot query returns null
    
              return Center(
                child: CircularProgressIndicator(),
                //then display the circular progress indicator
              );
            }
            final messages = snapshot.data.documents.reversed;
            //store in the messages variable the query of the latest data [documents] posted to Firebase
    
            List<MessageBubble> messageBubbles = [];
            //establish a list (messageWidgets) to store the contents of the documents
    
            for (var message in messages) {
              //build for in loops to retrieve the data in messages storing to the variable message to call the data of each field within a document in the messages collection
    
              final messageText = message.data['text'];
              //retrieve the data stored in the text field and save to the variable messageText
              final messageSender = message.data['sender'];
              //retrieve the data stored in the sender field and save to the variable messageSender
    
              final currentUser = loggedInUser.email;
    
              final messageBubble = MessageBubble(
                sender: messageSender,
                text: messageText,
                isMe: currentUser == messageSender,
              );
              //display the data retrieved from the data stored in the messageText and messageSender variables within the text and sender properties esatablished in the MessageBubble widget
    
              messageBubbles.add(messageBubble);
              //add each document data (messageWidget) retrieved and add it to the List messageWidgets
            }
            return Expanded(
              //Expanded - limit to available space
              child: ListView(
                //make the area where this content is housed scrollable
                reverse: true,
                padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
                children: messageBubbles,
                //return the data stored in messageWidgets
              ),
            );
          },
        );
      }
    }
    
    class MessageBubble extends StatelessWidget {
      MessageBubble({
        this.sender,
        this.text,
        this.isMe,
      });
    
      final String sender;
      final String text;
      //establish sender and text properties to further clarify where the data housed in the messageText and messageSender variables will be displayed
      final bool isMe;
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: EdgeInsets.all(8.0),
          child: Column(
            crossAxisAlignment:
                isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
            //if I am the logged in user that sent the message display the text bubble on the right, otherwise display on the left
            children: <Widget>[
              Text(
                sender,
                style: TextStyle(color: Colors.black54),
              ),
              Material(
                elevation: 5.0,
                borderRadius: isMe
                    ? BorderRadius.only(
                        topLeft: Radius.circular(30.0),
                        bottomLeft: Radius.circular(30.0),
                        bottomRight: Radius.circular(30.0),
                      )
                    : BorderRadius.only(
                        topRight: Radius.circular(30.0),
                        bottomLeft: Radius.circular(30.0),
                        bottomRight: Radius.circular(30.0),
                      ),
                //change the orientation of the border radius
                color: isMe ? Colors.lightBlueAccent : Colors.white,
                //if I am the logged in user that sent the message display the text bubble in light blue, otherwise display in white
                child: Padding(
                  padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0),
                  child: Text(
                    text,
                    style: TextStyle(
                      fontSize: 15.0,
                      color: isMe ? Colors.white : Colors.black,
                      //if I am the logged in user that sent the message display the text in white, otherwise display in black
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }
    

    最佳答案

    在您的 Firestore 数据库中,为每个文档添加一个新的 int 键,并将其命名为 orderId并将值从 1 设置为 4。
    然后改变这一行

    _firestore.collection('messages').snapshots()
    
    对此:
    _firestore.collection('messages').orderBy('orderId', descending: true).snapshots()
    
    这样您就可以得到orderId 订购的文件。 . descending: true意味着您希望它们从高阶到低阶。

    关于firebase - 按时间顺序显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62841285/

    相关文章:

    ios - 现有 CollectionView 图像在滚动时发生变化

    ios - 如何使用事件 channel 将数据从 swift 流式传输到 flutter?

    dart - js 包 - 对象的接口(interface)

    Flutter BLoC 事件竞争条件

    javascript - firestore 查询中的条件 where 子句

    java - Firebase Android 聊天示例 : Failed to bounce to type

    flutter - 视频播放器在 flutter 2.0 中崩溃(空安全)

    flutter - 未处理的异常 : Converting object to an encodable object failed: Photography

    ios - 使用 CocoaPods 在多个目标中引用 Firebase 时,构建运行但存档失败

    flutter - 参数类型 'Object?' 无法分配给参数类型 'List'