首页 > 解决方案 > 在 React Native 应用程序中使用 firebase 时遇到一些困难 - 警告:遇到两个具有相同密钥的孩子

问题描述

我正在使用 firebase 和有天赋的聊天为反应本机应用程序构建消息传递组件。我对 React 不是超级强,并且在获取我在聊天中发送的消息以在 firebase 数据库中形成独特(私人)聊天时遇到一些问题。即,如果我更改用户对象,我希望它设置一个新的唯一聊天 ID,因此与每个联系人的每次聊天都是私密的(并且是持久的),但目前情况并非如此。

const firebaseConfig = {
  apiKey: '12345',
  authDomain: '12345',
  projectId: '12345',
  storageBucket: '12345',
  messagingSenderId: '12345',
  appId: '12345',
  measurementId: '12345',
};

if (firebase.apps.length === 0) {
  firebase.initializeApp(firebaseConfig);
}

function MessagesHomeScreen() {
  const [user, setUser] = useState(null);
  const [messages, setMessages] = useState([]);
  const [contact, setContact] = useState(null);
  const [chatID, setChatID] = useState('');

  useEffect(() => {
    readUser();
  }, []);

  useEffect(() => {
    uniqueChatID();
  }, [contact]);

  useEffect(() => {
    const fetchMessage = async () => {
      const unsubscribe = await firebase
        .firestore()
        .collection('messages')
        .doc(chatID)
        .collection('chats')
        .onSnapshot((querySnapshot) => {
          const messagesFirestore = querySnapshot
            .docChanges()
            .filter(({ type }) => type === 'added')
            .map(({ doc }) => {
              message = doc.data();
              return { ...message, createdAt: message.createdAt.toDate() };
            })
            .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
          appendMessages(messagesFirestore);
        });
      return () => unsubscribe();
    };
    fetchMessage();
  }, [chatID]);

  const readUser = async () => {
    const fetchUser = await userInfoStorage.getUserInfo();
    const userObj = JSON.parse(fetchUser);
    const user = { _id: userObj.uuid, name: userObj.first_name };
    setUser(user);
  };

  const appendMessages = useCallback(
    (messages) => {
      setMessages((previousMessages) =>
        GiftedChat.append(previousMessages, messages)
      );
    },
    [messages]
  );

  const handleSend = async (messages) => {
    const writes = messages.map((m) =>
      firebase
        .firestore()
        .collection('messages')
        .doc(chatID)
        .collection('chats')
        .add(m)
    );
    await Promise.all(writes);
  };

  const uniqueChatID = () => {
    const userUUID = user?._id;
    const contactUUID = contact;
    const chatID = [];
    chatID.push(userUUID);
    chatID.push(contactUUID);
    chatID.sort();
    const chatIDString = chatID.join('-');
    return setChatID(chatIDString);
  };

  if (!contact) {
    return <ContactList updateParent={(contact) => setContact(contact)} />;
  }

  if (user && contact) {
    return (
      <>
        <GiftedChat
          messages={messages}
          user={user}
          onSend={handleSend}
          scrollToBottom={true}
        />
        <Button
          title={'Chat With Another Contact'}
          onPress={() => setContact(null)}
        />
      </>
    );
  }
}

export default MessagesHomeScreen;

错误如下

警告:遇到两个孩子用同一个钥匙,e26d5caf-e048-4162-9b43-17aa6b554b75。密钥应该是唯一的,以便组件在更新时保持其身份。非唯一键可能会导致子项被复制和/或省略——这种行为不受支持,并且可能在未来的版本中发生变化。

标签: reactjsfirebasereact-native

解决方案


推荐阅读