将数据从 FireBase 检索到颤振项目时出错

Posted

技术标签:

【中文标题】将数据从 FireBase 检索到颤振项目时出错【英文标题】:Error while retrieving data from FireBase into flutter project 【发布时间】:2021-11-23 18:38:14 【问题描述】:

我正在使用 Flutter sdk 版本 2.12.0。我正在创建一个可用于与其他用户聊天的聊天应用程序。聊天记录将存储在 fireBase 中。我正在尝试检索我聊天的数据并使用 Stream Builder 小部件将其显示在屏幕上。 当我继续聊天时,数据应该会自动添加。

我收到以下错误:

Closure call with mismatched arguments: function '[]'
Receiver: Closure: () => Map<String, dynamic> from Function 'data':.
Tried calling: []("text")
Found: []() => Map<String, dynamic>

我无法确定哪个函数的参数不匹配。你能不能取悦我。这是我的代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flashchat1/constants.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class ChatScreen extends StatefulWidget 
  static String id='Chat_Screen';
  @override
  _ChatScreenState createState() => _ChatScreenState();


class _ChatScreenState extends State<ChatScreen> 
  final _fireStore = FirebaseFirestore.instance;//an instance of fireBase store that stored data created
  final _auth = FirebaseAuth.instance;//instance/object of fireBase auth that authorizes users is created
  late User loggedInUser;//LoggedInUser is of type FireBase user(now changed to user)
  late String messageText;
  @override
  void initState()
  
    super.initState();
    getCurrentUser();//calling the getCurrentUser
  
  void getCurrentUser()
  async
    try
    
      final user= await _auth.currentUser;//get the current user id/name/email.Also currentUser return a future so make it async by adding await and async keywords
      if(user!=null)
      
        loggedInUser=user ;//LoggedInUser = user contains email of the info
        print(loggedInUser.email);
      

    
    catch(e)
    
      print(e);
    
  // Under collection there is documents.Inside documents there are fields like type ,values etc.These fields contain our information
    Future<void> messageStream()//Using a stream it becomes very easy .U just need to click once after you run the app .Then u will be done.
    async //The snapShot here is FireBase's Query SnapShot
      await for(var snapshot in _fireStore.collection('messages').snapshots())//make a variable snapshot to store the entire items of the collection in fireBase (Look at the fireBase console there is a collection called messages).This collection takes the snapshot of all the iteams (not literal snapshot .Think it like a snapShot)
        for(var message in snapshot.docs)//make a variable message to access the snapShot.docs .(docs stands for Documentation.Look at the fireBase console)
        print(message.data());
      
    
  void getMessages()//(The problem with this is that we need to keep clicking on the onPressed button every single time the new message is sent .So it is not convinient
  async 
    final messages = await _fireStore.collection('messages').get();//to retrieve the data from fire base we are creating a variable message
   messages.docs;//retreive the data from document section under the collection in firestore
    for(var message in messages.docs)//since it is a messages.docs is a list we need to loop through it
       
        print(message.data());//print the data its messge.data()
     
  
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        leading: null,
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.close),
              onPressed: () 
                messageStream();
                //_auth.signOut();
                //Navigator.pop(context);
                //Implement logout functionality
              ),
        ],
        title: Text('⚡️Chat'),
        backgroundColor: Colors.lightBlueAccent,
      ),
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Expanded(
              child: StreamBuilder(
                stream:_fireStore.collection('messages').snapshots(),
                builder: (context, AsyncSnapshot snapshot) 
                  //This is Flutter's Async snapShot
                  //if(!snapshot.data)
                   // 
                     // return Center(
                      //child:  CircularProgressIndicator(
                        //backgroundColor:Colors.lightBlueAccent,
                      //),
                      //);
                    //
                  if(snapshot.hasData)//flutters async snapshot contains a query snapshot
                    final messages = snapshot.data.docs;
                    List<Text> messageWidgets = [];
                    for(var  message in messages)//Loop through the messages
                      
                        final messageText = message.data['text'];//retrieve the data under the text field in message collection
                        final messageSender = message.data['Sender'];//retrieve the data under the Sender field in message collection
                        final messageWidget = Text('$messageText from $messageSender');
                        messageWidgets.add(messageWidget);//add the text to the List messageWidget
                        
                        return Column(//
                          children: messageWidgets,//if u don't write else with a return it will show an error as null returned and null safety broken
                        );
                      
                  else
                    return Column();
                  
                  ,
              ),
            ),
            Container(
              decoration: kMessageContainerDecoration,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      onChanged: (value) 
                        messageText=value;//Whatever you chat will be stored in the variable String variable messageText
                      ,
                      decoration: kMessageTextFieldDecoration,
                    ),
                  ),
                  FlatButton(
                    onPressed: () 
                      _fireStore.collection('messages').add(
                        'text': messageText,//add the messages sent to fireStore under the messages object that we created manually
                        'Sender': loggedInUser.email,//add the current users email to the sender field
                      ,);
                    ,//goal is to send the data that we type here to the fireStore cloud
                    child: Text(
                      'Send',
                      style: kSendButtonTextStyle,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  

【问题讨论】:

【参考方案1】:

改变这个:

final messageText = message.data['text'];
final messageSender = message.data['Sender'];

进入这个:

final messageText = message.data()['text'];
final messageSender = message.data()['Sender'];

【讨论】:

谢谢伙计。我看到的是旧版本的教程,它有数据而不是数据()。:)

以上是关于将数据从 FireBase 检索到颤振项目时出错的主要内容,如果未能解决你的问题,请参考以下文章

从 Firebase 检索第二个项目时出错

如何使用颤振从firebase实时检索数据

如何从firebase直接检索数据到应用程序中?

使用 KOTLIN 从 firebase 检索数据时出错

如何在多行中显示从firebase检索的数据? [关闭]

将快照数据从一个 dart 文件传递​​到颤振项目中的另一个文件