如何订购firebase的文件?

Posted

技术标签:

【中文标题】如何订购firebase的文件?【英文标题】:How to order the documents of firebase? 【发布时间】:2020-02-17 20:48:31 【问题描述】:

我想创建一个聊天应用程序,我也使用过 firebase,但我无法订购文档,当您发送消息时它不符合列表的顺序,它会随机放置。

我认为这与 firebase 控制台中的文档类型有关,如果相关,我需要有关如何在新消息出现时对其进行排序的帮助,它将位于列表底部,反之亦然。

我尝试了 listview 和 listview.builder 并且我使用了 reverse 属性,但它对我不起作用。

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import '../constants.dart';

final _firestore = Firestore.instance;
FirebaseUser loggedInUser;

class ChatScreen extends StatefulWidget 
  static String routeName = 'chat_screen';

  @override
  _ChatScreenState createState() => _ChatScreenState();


class _ChatScreenState extends State<ChatScreen> 
  final messageTextController = TextEditingController();
  final _auth = FirebaseAuth.instance;
  String message;

  void getCurrentUser() async 
    try 
      final user = await _auth.currentUser();

      if (user != null) 
        loggedInUser = user;
      
     catch (e) 
      print(e);
    
  

  void getMessages() async 
    final messages = await _firestore.collection('message').getDocuments();
    for (var message in messages.documents) 
      print(message.data);
    
  

  void messagesStream() async 
    await for (var snapshot in _firestore.collection('messages').snapshots()) 
      for (var message in snapshot.documents) 
        print(message.data);
      
    
  

  @override
  void initState() 
    super.initState();

    getCurrentUser();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        leading: null,
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.close),
              onPressed: () 
                _auth.signOut();
                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) 
                        message = value;
                      ,
                      decoration: kMessageTextFieldDecoration,
                    ),
                  ),
                  FlatButton(
                    onPressed: () 
                      messageTextController.clear();
                      _firestore
                          .collection('messages')
                          .add('text': message, 'sender': loggedInUser.email);
                    ,
                    child: Text(
                      'Send',
                      style: kSendButtonTextStyle,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  


class MessagesStream extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return StreamBuilder<QuerySnapshot>(
      stream: _firestore.collection('messages').snapshots(),
      builder: (context, snapshot) 
        if (!snapshot.hasData) 
          return Center(
            child: CircularProgressIndicator(
              backgroundColor: Colors.lightBlueAccent,
            ),
          );
        
        final messages = snapshot.data.documents;

        List<MessageBubble> messageBubbles = [];
        for (var message in messages) 
          final messageText = message.data['text'];
          final messageSender = message.data['sender'];
          final currentUser = loggedInUser.email;

          final messageBubble = MessageBubble(
              sender: messageSender,
              text: messageText,
              isMe: currentUser == messageSender);

          messageBubbles.add(messageBubble);
        

        return Flexible(
          child: ListView.builder(
            itemCount: messages.length,
            itemBuilder: (context , index)
            return MessageBubble(
              isMe: loggedInUser.email == messages[index].data['sender'],
              text: messages[index].data['text'],
              sender: messages[index].data['sender'],
            );
          ,),
        );
      ,
    );
  


class MessageBubble extends StatelessWidget 
  MessageBubble(this.sender, this.text, this.isMe);

  final bool isMe;
  final String sender;
  final String text;

  @override
  Widget build(BuildContext context) 
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Column(
        crossAxisAlignment:
            isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
        children: <Widget>[
          Text(sender, style: TextStyle(fontSize: 12, color: Colors.black54)),
          Material(
              elevation: 5.0,
              borderRadius: isMe
                  ? BorderRadius.only(
                      topLeft: Radius.circular(30),
                      bottomLeft: Radius.circular(30),
                      topRight: Radius.circular(30),
                    )
                  : BorderRadius.only(
                      bottomLeft: Radius.circular(30),
                      topRight: Radius.circular(30),
                      bottomRight: Radius.circular(30)),
              color: isMe ? Colors.lightBlueAccent : Colors.white,
              child: Padding(
                padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
                child: Text(
                  text,
                  style: TextStyle(
                      color: isMe ? Colors.white : Colors.black54,
                      fontSize: 15),
                ),
              )),
        ],
      ),
    );
  




【问题讨论】:

【参考方案1】:

添加订单

void getMessages() async 
    final messages = await _firestore.collection('message').orderBy("created_at", descending: true).getDocuments();
    for (var message in messages.documents) 
      print(message.data);
    
  

  void messagesStream() async 
    await for (var snapshot in _firestore.collection('messages').orderBy("created_at", descending: true).snapshots()) 
      for (var message in snapshot.documents) 
        print(message.data);
      
    
  

【讨论】:

【参考方案2】:

Cloud Firestore 中的文档没有隐式排序。

如果您想按特定顺序显示结果,则必须确保每个文档都包含确定其顺序所需的信息。通常这意味着您包含一个带有文档创建时间时间戳的字段。

有了这样的字段,您就可以使用orderBy() 按特定顺序检索文档:

await _firestore.collection('message').orderBy('timestamp').getDocuments()

【讨论】:

【参考方案3】:

检查一下,完美运行群聊应用程序(如果你想从 firebase 获取数据)。

 class MessageStream extends StatelessWidget 


 @override

 Widget build(BuildContext context) 
 return StreamBuilder<QuerySnapshot>(

  stream: _firestore.collection("messages").orderBy("time").snapshots(),

  builder: (context, snapshot) 

    if (!snapshot.hasData) 

      return Center(
        child: CircularProgressIndicator(

          backgroundColor: Colors.amber,

        ),
      );
    
    final messages = snapshot.data.documents.reversed;


    List<MessageBubble> messageBubbles = [];



    for (var message in messages) 

      final messageText = message.data["text"];

      final messageSender = message.data["sender"];

      final messageTime = message.data["time"];

      final currentUser = loggedInUser.email;


      final messageBubble = MessageBubble(

        sender: messageSender,

        text: messageText,

        isMe: currentUser == messageSender,

        time: messageTime,
      );
      messageBubbles.add(messageBubble);
    
    return Expanded(

      child: ListView(

        reverse: true,
        padding: EdgeInsets.all(10),

        children: messageBubbles,
      ),
    );
  ,
 );
 

【讨论】:

以上是关于如何订购firebase的文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个孩子 Firebase 中按孩子订购

Firebase 数据库 Rest Api:如何使用未知节点订购

使用 Firebase 订购 [关闭]

如何仅获取文档 ID [Firebase-Flutter]

如何对firebase firestore中的节点求和?

如何根据密钥对 Firebase 控制台中的节点进行排序