简体   繁体   中英

Flutter StreamBuilder widget Error : type ' () => Map<String, dynamic >' is not a subtype of type 'DocumentSnapshot<Object?>' in type cast

Error: type ' () => Map<String, dynamic >' is not a subtype of type 'DocumentSnapshot<Object?>' in type cast.

Below is the code sample of my chat screen which is one of the major component of my chat appllication where I wanted to build a stream of messages using the firebase but this gives an error app works completely fine till this screen but after this screen it throws an error please help me resolve this issue, I am using Streambuilder widget, please look into it

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:lets_chat/constant.dart';
import 'package:firebase_auth/firebase_auth.dart';

//final _firestore = FirebaseFirestore.instance;
//FirebaseUser = loggedInUser;

late User loggedInUser;

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

class _ChatScreenState extends State<ChatScreen> {
  final messageTextController = TextEditingController();
  final _fireStore = FirebaseFirestore.instance;
  final _auth = FirebaseAuth.instance;

  late String messageText;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    getCurrentUser();
  }

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

  void messagesStream() async {
    await for (var snapshot in _fireStore.collection('messages').snapshots()) {
      for (var messages in snapshot.docs) {
        print(messages.data);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: null,
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.close),
              onPressed: () {
                //Implement logout functionality
              }),
        ],
        title: Text('⚡️Chat'),
        backgroundColor: Colors.lightBlueAccent,
      ),
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            StreamBuilder<QuerySnapshot>(
              stream: _fireStore.collection('messages').snapshots(),
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                }
                final messages = snapshot.data?.docs;
                List<MessageBubble> messageBubbles = [];
                for (var message in messages!) {
                  final messageText =
                      (message.data as DocumentSnapshot)['text'];
                  final messageSender =
                      (message.data as DocumentSnapshot)['sender'];

                  final currentUser = loggedInUser.email;

                  final messageBubble = MessageBubble(
                    sender: messageSender,
                    text: messageText,
                    loggedUser: currentUser == messageSender,
                  );
                  messageBubbles.add(messageBubble);
                }
                return Expanded(
                  child: ListView(
                    children: messageBubbles,
                  ),
                );
              },
            ),
            Container(
              decoration: kMessageContainerDecoration,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      controller: messageTextController,
                      onChanged: (value) {
                        messageText = value;
                      },
                      decoration: kMessageTextFieldDecoration,
                    ),
                  ),
                  TextButton(
                    onPressed: () {
                      _fireStore.collection('messages').add({
                        'text': messageText,
                        'sender': loggedInUser.email,
                      });
                    },
                    child: Text(
                      'Send',
                      style: kSendButtonTextStyle,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

  final String sender;
  final String text;
  final bool loggedUser;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          Text(
            'sender',
            style: TextStyle(
              color: Colors.pink,
            ),
          ),
          Material(
              elevation: 5.0,
              borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(20.0),
                  bottomLeft: Radius.circular(20.0),
                  bottomRight: Radius.circular(20.0)),
              color: loggedUser
                  ? Colors.pinkAccent.shade200
                  : Colors.blueAccent.shade200,
              child: Padding(
                  padding:
                      EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
                  child: Text('$text from $sender'))),
        ],
      ),
    );
  }
}

Issue with your code is that you're trying to do message.data as DocumentSnapshot which is trying to cast () => Map<String, dynamic> (returned by .data ) to a DocumentSnapshot , which is incorrect.

message is a QuerySnapshot and you need to use data() method to access the fields.

final messages = snapshot.data?.docs;
List<MessageBubble> messageBubbles = [];
for (var message in messages!) {
  final messageText = message.data()['text'];
  final messageSender = message.data()['sender'];
  // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM