Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase 按时间顺序显示信息_Firebase_Flutter_Dart_Google Cloud Firestore - Fatal编程技术网

Firebase 按时间顺序显示信息

Firebase 按时间顺序显示信息,firebase,flutter,dart,google-cloud-firestore,Firebase,Flutter,Dart,Google Cloud Firestore,当使用Dart/FLIFT连接到Firebase时,我的消息按时间顺序显示存在一些问题。在ListView和查询Firebase时尝试了反向顺序,但无效 使用Firebase云Firestore作为后端。我删除了firebase中的集合,将反向属性添加到数据检索和ListView中,但问题仍然存在 我在Firebase中的数据库结构如下: 收集:信息/ 文件/ 字段(字符串:文本,字符串:发件人) 我可能需要设置一个integer属性和字段,以按消息出现的顺序显示消息,但不确定如何执行 下面

当使用Dart/FLIFT连接到Firebase时,我的消息按时间顺序显示存在一些问题。在ListView和查询Firebase时尝试了反向顺序,但无效

使用Firebase云Firestore作为后端。我删除了firebase中的集合,将反向属性添加到数据检索和ListView中,但问题仍然存在

我在Firebase中的数据库结构如下:

  • 收集:信息/
  • 文件/
  • 字段(字符串:文本,字符串:发件人)
我可能需要设置一个integer属性和字段,以按消息出现的顺序显示消息,但不确定如何执行

下面是问题的屏幕截图和屏幕代码

1,2,3,4应该按时间顺序出现

final\u firestore=firestore.instance;
FirebaseUser日志用户;
类ChatScreen扩展StatefulWidget{
静态常量字符串id='chat_screen';
@凌驾
_ChatScreenState createState()=>\u ChatScreenState();
}
类_ChatScreenState扩展状态{
最终消息TextController=TextEditingController();
final _auth=FirebaseAuth.instance;
字符串消息文本;
@凌驾
void initState(){
super.initState();
getCurrentUser();
//在屏幕初始化时检索用户凭据
}
void getCurrentUser()异步{
试一试{
最终用户=等待_auth.currentUser();
//如果有人登录,这将显示给当前用户
如果(用户!=null){
//如果我们有一个已登录的用户
loggedInUser=用户;
//将[logged in]用户保存到loggedInUser变量
}
}捕获(e){
印刷品(e);
}
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
前导:空,
行动:[
图标按钮(
图标:图标(Icons.close),
已按下:(){
//实现注销功能
_auth.signOut();
//注销用户
Navigator.pop(上下文);
}),
],
标题:文本('⚡️聊天室),,
背景颜色:Colors.lightBlueAccent,
),
正文:安全区(
子:列(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
crossAxisAlignment:crossAxisAlignment.stretch,
儿童:[
MessagesStream(),
容器(
装饰:kMessageContainerDecoration,
孩子:排(
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
扩大(
孩子:TextField(
控制器:messageTextController,
一旦更改:(值){
messageText=值;
//将文本输入字段的输入值存储为变量messageText
},
装饰:KMessageExtField装饰,
),
),
扁平按钮(
已按下:(){
messageTextController.clear();
//清除按钮按下时的文本字段
_firestore.collection('messages')。添加({
“文本”:messageText,
“发件人”:loggedInUser.email,
});
//根据Firebase中建立的信息和值记录信息和值
//从Firebase中建立的数据库集合和字段中检索
},
子:文本(
“发送”,
样式:ksendButtonExtStyle,
),
),
],
),
),
],
),
),
);
}
}
类MessagesStream扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回流生成器(
//StreamBuilder建立从Firebase控制台推送的数据流
//QuerySnapshot是从firebase控制台-->查询包含在firebase中的数据快照请求的数据类型
流:_firestore.collection('messages').snapshots(),
//流的源应该由messages集合组成。Snapshots()执行位置查询,以确定是否有新消息要推送
生成器:(上下文,快照){
//构建由流的上下文和快照查询组成的流
如果(!snapshot.hasData){
//如果快照查询返回null
返回中心(
子对象:CircularProgressIndicator(),
//然后显示循环进度指示器
);
}
最终消息=snapshot.data.documents.reversed;
//将发布到Firebase的最新数据[文档]的查询存储在messages变量中
列表messageBubbles=[];
//建立一个列表(messageWidgets)来存储文档的内容
for(消息中的var消息){
//build for in循环检索存储到变量message的消息中的数据,以调用messages集合中文档中每个字段的数据
final messageText=message.data['text'];
//检索文本字段中存储的数据并保存到变量messageText
final messageSender=message.data['sender'];
//检索存储在sender字段中的数据并保存到变量messageSender
最终currentUser=loggedInUser.email;
final messageBubble=messageBubble(
发件人:messageSender,
text:messageText,
isMe:currentUser==messageSender,
);
//显示从中的messageText和messageSender变量中存储的数据检索的数据
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.collection('messages').snapshots()
_firestore.collection('messages').orderBy('orderId', descending: true).snapshots()