0
votes

I'm trying to make a Snapchat-like app in Flutter with the messaging and stuff. The issue is weird. When the current user has no chat history and send a first message, a new chat is created and then the message is sent. and if he sends a another message under the story, not the chat view, then the message is sent and the chat log is updated.

Here is the issue. When I send a new message to another user's story for the first time, while already having a one chat history so this will be the second chat log, It creates a new chat log and sends the message, but when I send a second message to the same user, It creates a second chat log for the same user, sends the message, then for some reasons suddenly finds the prev chat log and updates that log and sends the message again. It keeps doing this -> Creating a new chat log and updates the old chat log repeatedly. And when I send another message to the previous user it created multiple chats and updates all of them with the new message.

The goal is to check if a chat exists between the users and if it does then simply just add a new message update the chat log, and if it doesn't then just create a new chat, and send the message then update the chat log.

By log, I mean like the recent message and timestamp you see before entering the actual chatroom.

The log looks like this, the numbered messages are for the first user and the letter messages are for the second user.

The chat's are being add to the current user's chats variable as an Inherited Widget.

Log:

flutter: No chats for me
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: 1 // Numbers are for the first user
flutter: User chats length: 0
flutter: CHAT IS EMPTY, CREATE NEW CHAT, AND SENT MESSAGE
flutter: New Chat Added
flutter: Message Sent
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: 2
flutter: User chats length: 1
flutter: CHAT IS NOT EMPTY
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: Message Sent
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: 3
flutter: User chats length: 1
flutter: CHAT IS NOT EMPTY
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: Message Sent
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: 4
flutter: User chats length: 1
flutter: CHAT IS NOT EMPTY
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: Message Sent
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: A // Letters are for the second user
flutter: User chats length: 1
flutter: CHAT IS NOT EMPTY
flutter: LOOKING FOR CHATS
flutter: DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT
flutter: New Chat Added
flutter: Message Sent
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: B
flutter: User chats length: 2
flutter: CHAT IS NOT EMPTY
flutter: LOOKING FOR CHATS
flutter: DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: New Chat Added
flutter: Message Sent
flutter: Message Sent
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: C
flutter: User chats length: 3
flutter: CHAT IS NOT EMPTY
flutter: LOOKING FOR CHATS
flutter: DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: New Chat Added
flutter: Message Sent
flutter: Message Sent
flutter: Message Sent
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: D
flutter: User chats length: 4
flutter: CHAT IS NOT EMPTY
flutter: LOOKING FOR CHATS
flutter: DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: New Chat Added
flutter: Message Sent
flutter: Message Sent
flutter: Message Sent
flutter: Message Sent
flutter: ----------------------------------------
flutter: STARTED
flutter: Message: 5 // When I send a message back to the first user
flutter: User chats length: 5
flutter: CHAT IS NOT EMPTY
flutter: LOOKING FOR CHATS
flutter: FOUND CHAT, MESSAGE SENT, UPDATING CHAT
flutter: LOOKING FOR CHATS
flutter: DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT
flutter: LOOKING FOR CHATS
flutter: DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT
flutter: LOOKING FOR CHATS
flutter: DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT
flutter: LOOKING FOR CHATS
flutter: DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT
flutter: New Chat Added
flutter: New Chat Added
flutter: New Chat Added
flutter: New Chat Added
flutter: Message Sent
flutter: Message Sent
flutter: Message Sent
flutter: Message Sent
flutter: Message Sent

Code:

Expanded(
  child: TextBox(
      margin: EdgeInsets.only(left: 25.0, right: 25.0),
      controller: this._textEditingController,
      focusNode: this._focusNode,
      hintText: 'Send a message',
      hintStyle: TextStyle(
        color: Config.tColor.withOpacity(0.8),
        fontSize: 15.0,
        fontWeight: FontWeight.w500,
      ),
      keyboardType: TextInputType.text,
      textInputAction: TextInputAction.next,
      textCapitalization: TextCapitalization.sentences,
      fontSize: 15.0,
      fontWeight: FontWeight.w500,
      autoFocus: false,
      autoCorrect: true,
      maxLines: null,
      onChanged: (s) {},
      onSubmitted: (s) async {
        User cUser = InheritedUser.of(context).user;
        print('----------------------------------------');
        print('STARTED');
        print('Message: $s');
        print('User chats length: ${cUser.chats.length}');
        DateTime now = DateTime.now();
        if (cUser.chats.isNotEmpty) {
          print('CHAT IS NOT EMPTY');
          cUser.chats.forEach((chat) async {
            print('LOOKING FOR CHATS');
            if (chat.users.contains(widget.posts[this._index].user) && chat.users.contains(APIs().users.collection.document(cUser.userID))) {
              print('FOUND CHAT, MESSAGE SENT, UPDATING CHAT');
              await this._sendMessage(
                  cUser: cUser,
                  chatID: chat.chatID,
                  messageID: APIs().chats.collection.document().documentID,
                  type: 'Text',
                  message: s,
                  now: now,
                  onSuccess: () {
                    print('Message Sent');
                    this._textEditingController.text = '';
                    FocusScope.of(context).requestFocus(FocusNode());
                    this._countDownSubscription.resume();
                    return;
                  });
              return;
            } else {
              print('DID NOT FIND CHAT, CREATED NEW CHAT, MESSAGE SENT');
              await this._createChat(
                  cUser: cUser,
                  now: now,
                  then: (chatID) async {
                    await this._sendMessage(
                        cUser: cUser,
                        chatID: chatID,
                        messageID: APIs().chats.collection.document().documentID,
                        type: 'Text',
                        message: s,
                        now: now,
                        onSuccess: () {
                          print('Message Sent');
                          this._textEditingController.text = '';
                          FocusScope.of(context).requestFocus(FocusNode());
                          this._countDownSubscription.resume();
                          return;
                        });
                    return;
                  });
              return;
            }
          });
        } else {
          print('CHAT IS EMPTY, CREATE NEW CHAT, AND SENT MESSAGE');
          await this._createChat(
              cUser: cUser,
              now: now,
              then: (chatID) async {
                await this._sendMessage(
                    cUser: cUser,
                    chatID: chatID,
                    messageID: APIs().chats.collection.document().documentID,
                    type: 'Text',
                    message: s,
                    now: now,
                    onSuccess: () {
                      print('Message Sent');
                      this._textEditingController.text = '';
                      FocusScope.of(context).requestFocus(FocusNode());
                      this._countDownSubscription.resume();
                      return;
                    });
                return;
              });
          return;
        }
      },
      onTap: () {
        this._countDownSubscription.pause();
      }),
)

Why does it work when there's only one chat under the current user but gets messy when there's more than one?

1

1 Answers

1
votes

Okay, so I figured out the problem.......

Silly mistakes, the if statements inside the for each loop gets executed at every stage of the loop (I assumed it would only call at the if only it did exist or it didn't exist for some reason, I guess I was tired or something...) because it checks for every single chat at that point if it matches or not. If it doesn't match then it creates a new chat and when it does match it just updates it.

So a simple solution:

Expanded(
  child: TextBox(
      margin: EdgeInsets.only(left: 25.0, right: 25.0),
      controller: this._textEditingController,
      focusNode: this._focusNode,
      hintText: 'Send a message',
      hintStyle: TextStyle(
        color: Config.tColor.withOpacity(0.8),
        fontSize: 15.0,
        fontWeight: FontWeight.w500,
      ),
      keyboardType: TextInputType.text,
      textInputAction: TextInputAction.next,
      textCapitalization: TextCapitalization.sentences,
      fontSize: 15.0,
      fontWeight: FontWeight.w500,
      autoFocus: false,
      autoCorrect: true,
      maxLines: null,
      onChanged: (s) {},
      onSubmitted: (s) async {
        User cUser = InheritedUser.of(context).user;
        DateTime now = DateTime.now();

        // Changes Start Here...
        if (cUser.chats.isNotEmpty) {
          String chatID;
          bool doesExists = false;

          for (final c in cUser.chats) {
            if (c.users.contains(widget.posts[this._index].user)) {
              chatID = c.chatID;
              doesExists = true;
              break;
            }
          }

          if (doesExists) {
            await this._sendMessage(
                cUser: cUser,
                chatID: chatID,
                messageID: APIs().chats.collection.document().documentID,
                type: 'Text',
                message: s,
                now: now,
                onSuccess: () {
                  this._textEditingController.text = '';
                  FocusScope.of(context).requestFocus(FocusNode());
                  this._countDownSubscription.resume();
                });
          } else {
            await this._createChat(
                cUser: cUser,
                now: now,
                then: (chatID) async {
                  await this._sendMessage(
                      cUser: cUser,
                      chatID: chatID,
                      messageID: APIs().chats.collection.document().documentID,
                      type: 'Text',
                      message: s,
                      now: now,
                      onSuccess: () {
                        this._textEditingController.text = '';
                        FocusScope.of(context).requestFocus(FocusNode());
                        this._countDownSubscription.resume();
                      });
                });
          }
        } else {
          await this._createChat(
              cUser: cUser,
              now: now,
              then: (chatID) async {
                await this._sendMessage(
                    cUser: cUser,
                    chatID: chatID,
                    messageID: APIs().chats.collection.document().documentID,
                    type: 'Text',
                    message: s,
                    now: now,
                    onSuccess: () {
                      this._textEditingController.text = '';
                      FocusScope.of(context).requestFocus(FocusNode());
                      this._countDownSubscription.resume();
                    });
              });
        }
      },
      onTap: () {
        this._countDownSubscription.pause();
      }),
)

Sometimes it just takes a minute away from coding for a solution to come to you.