Home > database >  Unhandled Exception: Invalid argument: Instance of 'User' in flutter
Unhandled Exception: Invalid argument: Instance of 'User' in flutter

Time:01-12

I'm following a course as a beginner in which we are doing a chat app. The course is a little bit old so I need to add some fixes to the code (on the one side it is good because I'm learning problem-solving). The app is working, log in and registration also working correctly. The app is using Firebase_auth and FirebaseFirestore. After signing in you can see the chat screen with a place to display messages and Row with TextField and send Button. After entering a message and hitting send Button message doesn't show up and I receive an error as the title says. Below, you can find more details:

I/TextInputPlugin(29334): Composing region changed by the framework. Restarting the input method.
W/IInputConnectionWrapper(29334): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper(29334): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(29334): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper(29334): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(29334): endBatchEdit on inactive InputConnection
E/flutter (29334): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument: Instance of 'User'
E/flutter (29334): #0      StandardMessageCodec.writeValue (package:flutter/src/services/message_codecs.dart:466:7)
E/flutter (29334): #1      FirestoreMessageCodec.writeValue (package:cloud_firestore_platform_interface/src/method_channel/utils/firestore_message_codec.dart:119:13)
E/flutter (29334): #2      StandardMessageCodec.writeValue.<anonymous closure> (package:flutter/src/services/message_codecs.dart:463:9)
E/flutter (29334): #3      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
E/flutter (29334): #4      StandardMessageCodec.writeValue (package:flutter/src/services/message_codecs.dart:461:13)
E/flutter (29334): #5      FirestoreMessageCodec.writeValue (package:cloud_firestore_platform_interface/src/method_channel/utils/firestore_message_codec.dart:119:13)
E/flutter (29334): #6      StandardMessageCodec.writeValue.<anonymous closure> (package:flutter/src/services/message_codecs.dart:463:9)
E/flutter (29334): #7      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
E/flutter (29334): #8      StandardMessageCodec.writeValue (package:flutter/src/services/message_codecs.dart:461:13)
E/flutter (29334): #9      FirestoreMessageCodec.writeValue (package:cloud_firestore_platform_interface/src/method_channel/utils/firestore_message_codec.dart:119:13)
E/flutter (29334): #10     StandardMethodCodec.encodeMethodCall (package:flutter/src/services/message_codecs.dart:604:18)
E/flutter (29334): #11     MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:285:34)
E/flutter (29334): #12     MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:472:12)
E/flutter (29334): #13     MethodChannelDocumentReference.set (package:cloud_firestore_platform_interface/src/method_channel/method_channel_document_reference.dart:32:52)
E/flutter (29334): #14     _JsonDocumentReference.set (package:cloud_firestore/src/document_reference.dart:166:22)
E/flutter (29334): #15     _JsonCollectionReference.add (package:cloud_firestore/src/collection_reference.dart:109:23)
E/flutter (29334): #16     _ChatScreenState.build.<anonymous closure> (package:flash_chat_flutter/screens/chat_screen.dart:86:73)
E/flutter (29334): #17     _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21)
E/flutter (29334): #18     GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
E/flutter (29334): #19     TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
E/flutter (29334): #20     BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)
E/flutter (29334): #21     BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:239:7)
E/flutter (29334): #22     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:615:9)
E/flutter (29334): #23     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
E/flutter (29334): #24     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
E/flutter (29334): #25     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
E/flutter (29334): #26     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
E/flutter (29334): #27     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
E/flutter (29334): #28     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:460:19)
E/flutter (29334): #29     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:440:22)
E/flutter (29334): #30     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:337:11)
E/flutter (29334): #31     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:395:7)
E/flutter (29334): #32     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:357:5)
E/flutter (29334): #33     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:314:7)
E/flutter (29334): #34     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:295:7)
E/flutter (29334): #35     _invoke1 (dart:ui/hooks.dart:167:13)
E/flutter (29334): #36     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341:7)
E/flutter (29334): #37     _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
E/flutter (29334): 
D/InsetsController(29334): show(ime(), fromIme=true)

Above details are displayed when I'm using the flutter run command.


When I'm using RUN/START DEBUGGING error pops up in error_patch.dart at line external static Never _throw(Object error, StackTrace stackTrace); . Also in DEBUG CONSOLE I have this:

I/TextInputPlugin(29642): Composing region changed by the framework. Restarting the input method.
W/IInputConnectionWrapper(29642): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper(29642): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(29642): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper(29642): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(29642): endBatchEdit on inactive InputConnection
D/InsetsController(29642): show(ime(), fromIme=true)


Below my chat_screen.dart code:

import 'package:flash_chat_flutter/screens/welcome_screen.dart';
import 'package:flutter/material.dart';
import 'package:flash_chat_flutter/constants.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

// late FirebaseAuth loggedInUser;
User? loggedInUser = FirebaseAuth.instance.currentUser;

class ChatScreen extends StatefulWidget {
  const ChatScreen({super.key});

  static String id = 'chat_screen';

  @override
  State<ChatScreen> createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final messageTextController = TextEditingController();

  var messageText = '';

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

  User? getCurrentUser() {
    try {
      // final user = FirebaseAuth.instance.currentUser;
      if (loggedInUser != null) {
        return loggedInUser;
      }
    } catch (e) {
      print(e);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: null,
        actions: <Widget>[
          IconButton(
              icon: const Icon(Icons.close),
              onPressed: () {
                FirebaseAuth.instance.signOut();
                if (mounted) return;
                Navigator.pop(context, WelcomeScreen.id);
              }),
        ],
        title: const Text('⚡️Chat'),
        backgroundColor: Colors.lightBlueAccent,
      ),
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            const Expanded(
              child: MessagesStream(),
            ),
            Container(
              decoration: kMessageContainerDecoration,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      controller: messageTextController,
                      onChanged: (value) {
                        setState(() {
                          messageText = value;
                        });
                      },
                      decoration: kMessageTextFieldDecoration,
                    ),
                  ),
                  TextButton(
                    onPressed: () {
                      print(loggedInUser);
                      FirebaseFirestore.instance.collection('messages').add(
                        {
                          'text': messageText,
                          'sender': loggedInUser,
                        },
                      );
                      messageTextController.clear();
                    },
                    child: const Text(
                      'Send',
                      style: kSendButtonTextStyle,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class MessagesStream extends StatelessWidget {
  const MessagesStream({super.key});

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
      stream: FirebaseFirestore.instance.collection('messages').snapshots(),
      builder: (context, snapshot) {
        // if (!snapshot.hasData) {
        //   return const Center(
        //     child: CircularProgressIndicator(
        //       backgroundColor: Colors.lightBlueAccent,
        //     ),
        //   );
        // }

        if (snapshot.hasError) {
          return const Center(
            child: Text('Something were wrong!'),
          );
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(
            child: CircularProgressIndicator(
              backgroundColor: Colors.lightBlueAccent,
            ),
          );
        }

        final messages = snapshot.data!.docs.reversed;

        List<MessageBubble> messageBubbles = [];
        if (messages != null) {
          for (var message in messages) {
            final messageText = message['text'];
            final messageSender = message['sender'];

            var currentUser = loggedInUser;

            final messageBubble = MessageBubble(
              sender: messageSender,
              text: messageText,
              isMe: currentUser == messageSender,
            );

            messageBubbles.add(messageBubble);
          }
        }
        return ListView(
          reverse: true,
          padding: const EdgeInsets.symmetric(
            horizontal: 10.0,
            vertical: 20.0,
          ),
          children: messageBubbles,
        );
      },
    );
  }
}

class MessageBubble extends StatelessWidget {
  const MessageBubble({
    super.key,
    required this.sender,
    required this.text,
    required this.isMe,
  });

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

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(10.0),
      child: Column(
        crossAxisAlignment:
            isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
        children: [
          Text(
            sender,
            style: const TextStyle(
              fontSize: 12.0,
              color: Colors.black54,
            ),
          ),
          Material(
            borderRadius: isMe
                ? const BorderRadius.only(
                    topLeft: Radius.circular(30.0),
                    bottomLeft: Radius.circular(30.0),
                    bottomRight: Radius.circular(30.0),
                  )
                : const BorderRadius.only(
                    topRight: Radius.circular(30.0),
                    bottomRight: Radius.circular(30.0),
                    bottomLeft: Radius.circular(30.0),
                  ),
            elevation: 5.0,
            color: isMe ? Colors.lightBlueAccent : Colors.white,
            child: Padding(
              padding: const EdgeInsets.symmetric(
                vertical: 10.0,
                horizontal: 20.0,
              ),
              child: Text(
                text,
                style: TextStyle(
                  color: isMe ? Colors.white : Colors.black54,
                  fontSize: 15.0,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

I have tried to try answer to this but I'm failed :( Can someone help me and explain where I messed up my code?

Thank you in advande

CodePudding user response:

The Firestore database can only store data of the types that are shown in the documentation of supported data types. You'll note that FirebaseUser is not one of those types, which is why it throws an error when you try to save an object of that type.

You'll want to instead store the specific properties of that user object that you want in the database, e.g.

FirebaseFirestore.instance.collection('messages').add(
  {
    'text': messageText,
    'senderUid': loggedInUser.uid,
    'senderName': loggedInUser.displayName,
  },
);
  • Related