【问题标题】:How can I add data from the Firebase database in a reversed order? [closed]如何以相反的顺序从 Firebase 数据库添加数据? [关闭]
【发布时间】:2021-04-20 23:09:04
【问题描述】:

我目前正在开发一个聊天应用程序。问题是,当有人键入内容时,它会随机显示在聊天屏幕上(在用户注册并登录后)。

我希望它看起来像一个普通的聊天应用程序,所以最后一条消息应该在屏幕底部。我什至颠倒了数据和列表视图,但是没有用。

我的代码:

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

final _firestore=FirebaseFirestore.instance;
User loggedInUser;

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

class _ChatScreenState extends State<ChatScreen> {

  final messageTextController = TextEditingController();
  final _auth = FirebaseAuth.instance;

  String messageText;

  void initState(){
    super.initState();
    getCurrentUser();
  }

  void getCurrentUser()async{
    try{
      final currentUser =  await _auth.currentUser;
      if(currentUser!=null){
        loggedInUser=currentUser;
      }
    }
    catch(e){
      print(e);
    }
  }


  @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) {
                        messageText = value;
                      },
                      decoration: kMessageTextFieldDecoration,
                    ),
                  ),
                  FlatButton(
                    onPressed: () {
                      messageTextController.clear();
                      _firestore.collection('messages').add({
                        'text': messageText,
                        '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.docs.reversed;
        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 Expanded(
          child: ListView(
            reverse: true,
            padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
            children: messageBubbles,
          ),
        );
      },
    );
  }
}

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

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

  @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.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: 20.0),
              child: Text(
                text,
                style: TextStyle(
                  color: isMe ? Colors.white : Colors.black54,
                  fontSize: 15.0,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}


【问题讨论】:

  • 嗨,在 firebas 上创建一个名为 createdAt 的部分是有意义的,但不幸的是,在我应用你的代码部分后,我开始在聊天屏幕上看不到任何东西,我不明白为什么。跨度>
  • 嗯....我刚刚修复的查询中有错字,所以您可能想尝试一下。
  • 现在可以了,:) 祝你有美好的一天。

标签: firebase flutter google-cloud-firestore


【解决方案1】:

您添加消息:

_firestore.collection('messages').add({
  'text': messageText,
  'sender': loggedInUser.email,
});

Firestore 没有任何内置的文档默认顺序。如果您希望能够订购文档,则需要为每个文档添加一个值以允许这样做。

例如,您可以添加文档创建时间的时间戳:

_firestore.collection('messages').add({
  'text': messageText,
  'sender': loggedInUser.email,
  'createdAt': FieldValue.serverTimestamp()
});

通过使用FieldValue.serverTimestamp(),服务器将自动填充此字段,然后您可以在读取数据时使用:

stream: _firestore.collection('messages').orderBy('createdAt', descending: true).snapshots()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 2023-04-01
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    相关资源
    最近更新 更多