How to order the documents of firebase?

会有一股神秘感。 提交于 2020-02-07 01:36:53

问题


I want to create a chat app, I have used firebase as well but I can't order documents where when you send a message it doesn't be with the order of the list it goes in a random place.

I think this is related to the sort of documents in firebase console if related I want help on how to sort this when a new message comes it will be at the bottom of the list and vice versa.

I have tried listview and listview.builder and I have used the reverse property but it didn't work with me .

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:


Add order by

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:


There is no implicit ordering for documents in Cloud Firestore.

If you want to show the results in a specific order, you will have to make sure each document includes the necessary information to determine its order. Typically this means that you include a field with the timestamp of when the document was created.

With such a field in place, you can then use orderBy() to retrieve the documents in a specific order:

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



回答3:


Check This out, perfectly running for a group chat app(if you want to get data from 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,
      ),
    );
  },
 );
 }
}


来源:https://stackoverflow.com/questions/58491785/how-to-order-the-documents-of-firebase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!