title: React native randomly crashes with error 'Attempted to remove more RCTKeyboardObserver listeners than added'
body: <p>My react native project on iOS simulator crashes randomly with this error when I open and close the ChatRoom screen, I guess it's a problem with the react native gifted chat library I'm not sure, that's the only external library I use in that screen.</p>
  <p>I have tried Keyboard remove listener solution <code>Keyboard.addListener(&quot;keyboardWillShow&quot;).remove();</code> from <a href="https://github.com/rgommezz/react-native-offline/issues/55" rel="nofollow noreferrer">https://github.com/rgommezz/react-native-offline/issues/55</a> in my App.js file but it don't work.</p>
  <p>I have added the code of the screen where this crash randomly occurs. Project versions are &quot;react&quot;: &quot;17.0.2&quot;, &quot;react-native&quot;: &quot;0.66.4&quot;, &quot;react-native-gifted-chat&quot;: &quot;^0.16.3&quot;.</p>
  <p><strong>ChatRoom</strong></p>
  <pre><code>const ChatRoom = ({ navigation, route }) =&gt; {
    React.useLayoutEffect(() =&gt; {
      navigation.setOptions({
        title: name,
      });
    }, [navigation, name]);
  
    React.useEffect(() =&gt; {
      mounted.current = true;
      async function fetch() {
        const response = await getUserData(receiverId);
        if (mounted.current) {
          setChatImage(response.userimg);
          setName(response.name);
        }
  
        const chat = await getChat(user.uid, userid);
  
        if (chat) {
          const unsubscribe = firestore()
            .collection(&quot;Messages&quot;)
            .where(&quot;chatid&quot;, &quot;==&quot;, chat)
            .onSnapshot((querySnapshot) =&gt; {
              const messages = querySnapshot
                .docChanges()
                .filter(({ type }) =&gt; type === &quot;added&quot;)
                .map(({ doc }) =&gt; {
                  const message = doc.data();
                  return {
                    ...message,
                    createdAt: message.createdAt.toDate(),
                  };
                })
                .sort((a, b) =&gt; b.createdAt.getTime() - a.createdAt.getTime());
              appendMessages(messages);
            });
  
          return () =&gt; unsubscribe();
        }
      }
      fetch();
      return () =&gt; (mounted.current = false);
    }, []);
  
    React.useEffect(() =&gt; {
      // set message state
      if (receiverId) {
        if (user.uid !== receiverId) {
          async function fetch() {
            const chat = await getChat(user.uid, userid);
            await markMsgStatus(user.uid, chat);
          }
          fetch();
        }
      }
    }, [receiverId]);
  
    const appendMessages = React.useCallback(
      (messages) =&gt; {
        setMessages((previousMessages) =&gt;
          GiftedChat.append(previousMessages, messages)
        );
      },
      [messages]
    );
  
    const handleSend = async (messages) =&gt; {
      // if there are no chats, create one
      const chat = await getChat(user.uid, userid);
      let chatid;
      if (!chat) {
        chatid = await createChat(user.uid, userid);
      }
  
      // increment the no of messages in the chat by one
      firestore()
        .collection(&quot;Chats&quot;)
        .doc(chat ? chat : chatid)
        .set(
          {
            noofmsgs: firestore.FieldValue.increment(1),
          },
          { merge: true }
        )
        .then(() =&gt; console.log(&quot;message count on chat increased by one&quot;))
        .catch((e) =&gt; console.log(e));
  
      // add the messages
      const writes = messages.map((m) =&gt;
        firestore()
          .collection(&quot;Messages&quot;)
          .add({
            ...m,
            sent: true,
            received: false,
            senderid: user.uid,
            receiverid: userid,
            chatid: chat ? chat : chatid,
          })
      );
      await Promise.all(writes);
  
      // add the latest msg to chat
      const writetochat = messages.find((m) =&gt;
        firestore()
          .collection(&quot;Chats&quot;)
          .doc(chat ? chat : chatid)
          .set(
            {
              latestmsg: m,
              latestmsgsender: user.uid,
              latestmsgreceiver: userid,
            },
            { merge: true }
          )
      );
      await Promise.all(writetochat);
    };
  
    return (
      &lt;View&gt;
        &lt;GiftedChat
          messages={messages}
          user={{
            _id: user.uid,
          }}
          onSend={handleSend}
          showAvatarForEveryMessage={true}
        /&gt;
      &lt;/View&gt;
    );
  };
  
  export default ChatRoom;
  
  </code></pre>