dart 聊天应用程序显示消息随机当用户发送消息和消息是不是在正确的顺序

wljmcqd8  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(84)

在完成我的教程后,我用firebase做了一个基本的聊天应用。但该应用程序并不总是按顺序显示消息。此外,我的消息应该从底部开始,但他们并不总是这样做。
我已经实现了像这样的firebase和firestore包,因为我在提到版本时收到了错误消息。

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.2
  animated_text_kit: ^4.1.1
  firebase_core:
  firebase_auth:
  cloud_firestore:
  modal_progress_hud: ^0.1.3

在教程中,它显示了你必须像下面的代码一样在文档后面添加.reversed。

final messages = snapshot.data.documents.reversed;

但是当我尝试做同样的事情时,文档属性不存在,我们必须使用.docs,然后我尝试在文档之后添加.reversed,但是问题仍然存在,消息随机出现。我还尝试从firebase中删除集合,如教程所示。
下面是获取消息流的代码。

class streamOfMessages extends StatelessWidget {
  const streamOfMessages({@required this.users,});
  final CollectionReference users;

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: users.snapshots(),
        // ignore: missing_return
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
          if(!snapshot.hasData){
            return Center(
              child: CircularProgressIndicator(
                backgroundColor: Colors.blueAccent,
              ),
            );
          }
          final messages = snapshot.data.docs.reversed;
          List<messageBubble> messageWidgets = [];
          for(var message in messages){
            final messageText = message.data()['text'];
            final messageSender = message.data()['sender'];
            final messageWidget = messageBubble(
              message: messageText,
              sender: messageSender,
              isMe: userEmail == messageSender,
            );
            messageWidgets.add(messageWidget);
          }
          return Expanded(
            child: ListView(
              children: messageWidgets,
              reverse: true,
            ),
          );
        });
  }
}

我也试着添加一个时间戳,但我认为我做错了什么。任何帮助都非常感谢谢谢。
我在ChatScreen dart文件中写了一段代码,在那里我定义了所有内容,比如显示消息和文本编辑。
其他一切工作正常,只是消息以错误的顺序显示。
下面是聊天屏幕的全部代码
任何帮助都非常感谢。

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

final _auth = FirebaseAuth.instance;
final _firestore = FirebaseFirestore.instance;
String userEmail;

class ChatScreen extends StatefulWidget {
  static String id = 'chat_screen';
  @override
  _ChatScreenState createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {

  final messageController = TextEditingController();
  CollectionReference users = FirebaseFirestore.instance.collection('messages');
  String messageText;

  @override
  void initState() {
    super.initState();
    loggeduser();
  }

  void loggeduser(){
    try{
      final user = _auth.currentUser;
      if(user != null){
       print(user.email);
       userEmail = user.email;
      }
    }catch(e){
      print(e);
    }
  }

  void getMessages() async {
    await for (var snapshot in _firestore.collection('messages').snapshots()){
      for (var message in snapshot.docs){
        print(message.data());
      }
    }
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: null,
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.logout),
              onPressed: () {
                _auth.signOut();
                Navigator.pop(context);
              }),
        ],
        title: Text('⚡️Chat'),
        centerTitle: true,
        backgroundColor: Colors.lightBlueAccent,
      ),
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            streamOfMessages(users: users),
            Container(
              decoration: kMessageContainerDecoration,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      controller: messageController,
                      onChanged: (value) {
                        messageText = value;
                      },
                      decoration: kMessageTextFieldDecoration,
                    ),
                  ),
                  FlatButton(
                    onPressed: () {
                      messageController.clear();
                      _firestore.collection('messages').add({
                        'text' : messageText,
                        'sender' : userEmail,
                      });
                    },
                    child: Text(
                      'Send',
                      style: kSendButtonTextStyle,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// ignore: camel_case_types
class streamOfMessages extends StatelessWidget {
  const streamOfMessages({@required this.users,});
  final CollectionReference users;

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: users.snapshots(),
        // ignore: missing_return
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot){
          if(!snapshot.hasData){
            return Center(
              child: CircularProgressIndicator(
                backgroundColor: Colors.blueAccent,
              ),
            );
          }
          final messages = snapshot.data.docs.reversed;
          List<messageBubble> messageWidgets = [];
          for(var message in messages){
            final messageText = message.data()['text'];
            final messageSender = message.data()['sender'];
            final messageWidget = messageBubble(
              message: messageText,
              sender: messageSender,
              isMe: userEmail == messageSender,
            );
            messageWidgets.add(messageWidget);
          }
          return Expanded(
            child: ListView(
              children: messageWidgets,
              reverse: true,
            ),
          );
        });
  }
}

// ignore: camel_case_types
class messageBubble extends StatelessWidget {
  final String  message;
  final String sender;
  final bool isMe;
  messageBubble({this.message, this.sender, this.isMe, this.time});
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Column(
        crossAxisAlignment: isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
        children: [
          Text('$sender',
            style: TextStyle(fontSize:10.0, color: Colors.black54),
          ),
          Material(
            borderRadius: isMe ? BorderRadius.only(topLeft: Radius.circular(30.0),bottomLeft: Radius.circular(30.0),bottomRight: Radius.circular(30.0)) :
            BorderRadius.only(bottomLeft: Radius.circular(30.0),bottomRight: Radius.circular(30.0),topRight: Radius.circular(30.0)),
            elevation: 5.0,
            color: isMe ? Colors.lightBlueAccent : Colors.white,
              child: Padding(
                padding: EdgeInsets.symmetric(vertical: 10.0,horizontal: 10.0),
                child: Text(message,
                style: TextStyle(fontSize: 16.0,
                    color: isMe ? Colors.white : Colors.black54),),
              )
          ),
        ],
      ),
    );
  }
}
vsdwdz23

vsdwdz231#

所以我找到了答案,你必须在代码中添加一个时间戳,并在列表中添加sort方法,问题就解决了。下面是修改的代码。
“.....”=表示代码相同,无需更改。

............
               Expanded(
                    child: TextField(
                      controller: messageController,
                      onChanged: (value) {
                        messageText = value;
                      },
                      decoration: kMessageTextFieldDecoration,
                    ),
                  ),
                  FlatButton(
                    onPressed: () {
                      messageController.clear();
                      _firestore.collection('messages').add({
                        'text' : messageText,
                        'sender' : userEmail,
                        'time' : DateTime.now(),   --------------> Change here
                      });
                      print(DateTime.now());
                    },
                    child: Text(
                      'Send',
                      style: kSendButtonTextStyle,
                    ),..............

下面的另一个变化

.............
     child: CircularProgressIndicator(
                    backgroundColor: Colors.blueAccent,
                  ),
                );
              }
              final messages = snapshot.data.docs.reversed;
              List<messageBubble> messageWidgets = [];
              for(var message in messages){
                final messageText = message.data()['text'];
                final messageSender = message.data()['sender'];
                final messageTime = message.data()['time'];   ---------> added
                final messageWidget = messageBubble(
                  message: messageText,
                  sender: messageSender,
                  isMe: userEmail == messageSender,
                  time: messageTime, -----------------------------------> Add this
                );
                messageWidgets.add(messageWidget);  -----------------------------> Add bot 
                messageWidgets.sort((a , b ) => b.time.compareTo(a.time)); ------> h lines
              }
              return Expanded(
                child: ListView(
                  children: messageWidgets,
                  reverse: true,
                ),
              );

下面另一个变化

.............
class messageBubble extends StatelessWidget {
  final String  message;
  final String sender;
  final bool isMe;
  final Timestamp time;  ------------------> This is added
  messageBubble({this.message, this.sender, this.isMe, this.time}); ----> add this.time
  @override
  Widget build(BuildContext context) {

相关问题