skip to Main Content

I am building a chatApp with a login Screen and a Register Screen. After authenticating it (register and login) you can start chatting with other users. I added a controller property to my textField after that my code is crashing even after removing the controller. The line of the error is not mentioned. As soon as its starts loading the chats I am getting an exception.

I tried removing the Expanded Widget and adding a SizedBox property instead of it.
I also tried adding shrinkWrap: true,for my ListView but to no luck.I am not able to find out the error here .

PLease do help !!

Here is the error:-

======== Exception caught by rendering library =====================================================
The following assertion was thrown during performLayout():
RenderBox was not laid out: RenderMouseRegion#5a758 relayoutBoundary=up7 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1929 pos 12: 'hasSize'


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

The relevant error-causing widget was: 
  TextField TextField:file:///D:/flashchat1/lib/screens/chat_screen.dart:86:22
When the exception was thrown, this was the stack: 
#2      RenderBox.size (package:flutter/src/rendering/box.dart:1929:12)
#3      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:117:21)
#4      RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#5      ChildLayoutHelper.layoutChild (package:flutter/src/rendering/layout_helper.dart:56:11)
#6      RenderFlex._computeSizes (package:flutter/src/rendering/flex.dart:829:43)
#7      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:931:32)
#8      RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#9      RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:233:12)
#10     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#11     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#12     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#13     ChildLayoutHelper.layoutChild (package:flutter/src/rendering/layout_helper.dart:56:11)
#14     RenderFlex._computeSizes (package:flutter/src/rendering/flex.dart:829:43)
#15     RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:931:32)
#16     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#17     RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:233:12)
#18     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#19     MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:171:12)
#20     _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:1097:7)
#21     MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:240:7)
#22     RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:404:14)
#23     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#24     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#25     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#26     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#27     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1388:11)
#28     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#29     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#30     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#31     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#32     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#33     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#34     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#35     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#36     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#37     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#38     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#39     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#40     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#41     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#42     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#43     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#44     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#45     RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3420:14)
#46     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#47     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
#48     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
#49     _RenderTheatre.performLayout (package:flutter/src/widgets/overlay.dart:745:15)
#50     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1713:7)
#51     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:885:18)
#52     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:453:19)
#53     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:883:13)
#54     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:319:5)
#55     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1143:15)
#56     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1080:9)
#57     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:996:5)
#61     _invoke (dart:ui/hooks.dart:166:10)
#62     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#63     _drawFrame (dart:ui/hooks.dart:129:31)
(elided 5 frames from class _AssertionError and dart:async)
The following RenderObject was being processed when the exception was fired: _RenderFocusTrapArea#698c0 relayoutBoundary=up6 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...  parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
...  constraints: BoxConstraints(unconstrained)
...  size: MISSING
RenderObject: _RenderFocusTrapArea#698c0 relayoutBoundary=up6 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
  parentData: offset=Offset(0.0, 0.0); flex=null; fit=null (can use size)
  constraints: BoxConstraints(unconstrained)
  size: MISSING
...  child: RenderMouseRegion#5a758 relayoutBoundary=up7 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...    parentData: <none> (can use size)
...    constraints: BoxConstraints(unconstrained)
...    size: MISSING
...    listeners: enter, exit
...    cursor: SystemMouseCursor(text)
...    child: RenderIgnorePointer#e8ea6 relayoutBoundary=up8 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...      parentData: <none> (can use size)
...      constraints: BoxConstraints(unconstrained)
...      size: MISSING
...      ignoring: false
...      ignoringSemantics: implicitly false
...      child: RenderSemanticsAnnotations#e40f4 relayoutBoundary=up9 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...        parentData: <none> (can use size)
...        constraints: BoxConstraints(unconstrained)
...        size: MISSING
...        child: RenderPointerListener#bba7b relayoutBoundary=up10 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
...          parentData: <none> (can use size)
...          constraints: BoxConstraints(unconstrained)
...          size: MISSING
...          behavior: translucent
...          listeners: down
====================================================================================================
I/TetheringManager(10454): registerTetheringEventCallback:com.example.flashchat1
W/DynamiteModule(10454): Local module descriptor class for providerinstaller not found.

Here is the code:-

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';
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
class ChatScreen extends StatefulWidget {
  static String id='Chat_Screen';
  @override
  _ChatScreenState createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final messageTextController = TextEditingController();
  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(
      resizeToAvoidBottomInset: false,
      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>[
            MessagesStream(),
            Container(
              decoration: kMessageContainerDecoration,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                     TextField(
                      controller:messageTextController,//add a controller to control the textField
                      onChanged: (value) {
                        messageText=value;//Whatever you chat will be stored in the variable String variable messageText
                      },
                      decoration: kMessageTextFieldDecoration,
                    ),
                  FlatButton(
                    onPressed: () {
                      messageTextController.clear();//clear the text in the TextField as soon as you press the Send button
                      _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,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class MessageBubble extends StatelessWidget {
MessageBubble({required this.sender,required this.text});
  final String sender;
  final String text;
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(10.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          Text(sender,
          style:TextStyle(
            fontSize:12.0,
            color:Colors.black54,
          )
          ),
          SizedBox(
            width:200,
            height:50,
            child: Material(
              borderRadius: BorderRadius.circular(20.0),
              elevation: 5.0,
              color:Colors.lightBlueAccent,
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical:10.0,horizontal: 20.0),
                child: Text('$text',
                  style:TextStyle(
                    color:Colors.white,
                    fontSize:15,
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );;
  }
}

class MessagesStream extends StatelessWidget {
  const MessagesStream({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream:_fireStore.collection('messages').snapshots(),
      builder: (context, AsyncSnapshot snapshot) {
        if(!snapshot.hasData){//flutters async snapshot contains a query snapshot
          return Center(
            child:CircularProgressIndicator(
              backgroundColor:Colors.lightBlueAccent,
            ),
          );
        }
        final messages = snapshot.data.docs;
        List<MessageBubble> messageBubbles = [];//messageBubbles is of the type MessageBubble
        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 messageBubble =MessageBubble(sender: messageSender, text: messageText,);
          messageBubbles.add(messageBubble);//add the text to the List messageWidget
        }
        return ListView(
            shrinkWrap: true,
            children:messageBubbles,
        );
      },
    );
  }
}

3

Answers


  1. I recommend using the bottomNavigationBar parameter to put your text field and send button that way it always stays bottom, and wrap your MessageStream with Expanded So that, It can take up remaining space.

    Please lemme know if you have any issues in the comments section, I will be glad to help you.

    Login or Signup to reply.
  2. Try adding Expand for the MessageStream. Because ListView, when rendering, needs to know the height. If you use Expand for it, it will know that the height for rendering is the extent of the Column .

    Login or Signup to reply.
    1. I put Expanded in your code and it worked.
    2. you can remove the message stream and uncomment my code to just see how it looks.
    3. I don’t have the stream builder result so I make a static list in your class and its works very well.
    Scaffold(
          backgroundColor: Colors.white,
          body: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              /*Expanded(
                child: ListView.builder(
                  itemBuilder: (context, index) => MessageBubble(
                    sender: "User1",
                    text: "Blah blah blah",
                  ),
                  shrinkWrap: true,
                  itemCount: 10,
                ),
              ),*/
              MessagesStream(),
              Container(
                child: Row(
                  children: [
                    Expanded(child: Text("Blah blah blah")),
                    ElevatedButton(onPressed: () {}, child: Text("Send"))
                  ],
                ),
              )
            ],
          ),
        );
    
    class MessagesStream extends StatelessWidget {
      const MessagesStream({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return StreamBuilder(
          builder: (context, AsyncSnapshot snapshot) {
            final messages = snapshot.data;
    
            List<MessageBubble> messageBubbles =
                []; //messageBubbles is of the type MessageBubble
            messageBubbles
                .add(MessageBubble(sender: "user1", text: "Blaah blah blah"));
            messageBubbles
                .add(MessageBubble(sender: "user1", text: "Blaah blah blah"));
            messageBubbles
                .add(MessageBubble(sender: "user1", text: "Blaah blah blah"));
            messageBubbles
                .add(MessageBubble(sender: "user1", text: "Blaah blah blah"));
            messageBubbles
                .add(MessageBubble(sender: "user1", text: "Blaah blah blah"));
            messageBubbles
                .add(MessageBubble(sender: "user1", text: "Blaah blah blah"));
            messageBubbles
                .add(MessageBubble(sender: "user1", text: "Blaah blah blah"));
            messageBubbles
                .add(MessageBubble(sender: "user1", text: "Blaah blah blah"));
            return ListView(
              shrinkWrap: true,
              children: messageBubbles,
            );
          },
        );
      }
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search