在 FlatList 的 renderItem 中执行 firestore 查询以传递数据以返回 Child [英] Performing firestore query in renderItem of FlatList to pass data to return Child

查看:58
本文介绍了在 FlatList 的 renderItem 中执行 firestore 查询以传递数据以返回 Child的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个学校项目,我被一个错误困住了 12 多个小时......

this is a school project and I have been stuck on a bug for more than 12 hours...

上下文是用户接受来自发件人的聊天请求,当我返回聊天标签时,会创建并显示一个新的聊天房间".所有这些都在 TabNavigator 中完成.

The context is user accepts a chat request from the sender and upon doing so, a new chat 'room' is created and shown when i go back to the Chats tab. All these are done in a TabNavigator.

我的预期结果是动态/自动加载 Chat 标签中的 ChatItem(即这些 ChatItem 位于 FlatList 中),当我当用户接受传入的聊天请求时.

My expected result is to dynamically/automatically load the ChatItem in the Chats tab (i.e. these ChatItems live in a FlatList) when I as a user accepts the incoming chat requests.

问题是我试图从 firestore 获取发件人的数据,但我一直未定义其数据.我对应用程序的初始加载从 firestore 获取所有用户数据并加载 Redux 商店.

The problem is that I am trying to get the sender's data from firestore but I keep getting undefined for its data. My initial load for the app gets all users data from firestore and loads up the Redux store.

流程:发件人发送聊天请求 ->更新 firestore 并且正在监听更改 ->接收者看到一个新的聊天请求(这有效)->接受 ->为发送者和接收者创建的新聊天房间"(应自动显示)

Flow: Sender sends chat request -> Updates firestore and the changes are being listened to -> Receiver sees a new chat request (this works) -> Accepts -> New chat 'room' created for sender and receiver (should show automatically)

我尝试不接收未定义发件人的方法:

Ways I have tried to not get an undefined sender:

  1. 接受聊天请求,更新 firestore,然后更新 Redux 存储.从据称"更新的 Redux 存储中检索所有用户数据.但它是未定义的
  2. 编写了一个侦听器来侦听 firestoreusers 集合中的更改,但是在呈现 FlatList 中的项目时速度慢了 1 步,并且我得到了未定义的发件人数据
  3. 编写条件检查以检查发件人的数据是否未定义,如果是,则执行 DIRECT firestore 查询以从 users 集合中获取发件人的数据.但我仍然没有定义.
  1. Accepting a chat request, updates firestore and then Redux store. Retrieve all users data from 'supposedly' updated Redux store. But it's undefined
  2. Wrote a listener to listen for changes in the users collection in firestore but it's 1 step slower when rendering the items in the FlatList and I get undefined sender's data
  3. Wrote conditional checks to check if sender's data is undefined, if yes, perform a DIRECT firestore query to get the sender's data from the users collection. But still I get undefined.

我怀疑所有这些都是由于 FlatList 再次重新渲染,但我不确定如何控制它.

I suspect all these is due to the FlatList re-rendering again but I'm not exactly sure how to control it.

我确实为 FlatList 中的道具 extraData 指定了一个状态.

I did specify a state for the prop extraData in the FlatList.

我已经用尽了所有可能的方法,做了所有的研究,但我已经筋疲力尽了.

I have exhausted all ways possible, did all research, and I'm dead flat exhausted.

感谢您的帮助,非常感谢.

I appreciate any help please, thank you so much.

这是ChatsOverviewScreen,清理了不必要的代码:

Here is the ChatsOverviewScreen, cleaned up unnecessary codes:

const ChatsOverviewScreen = ({ navigation }) => {
  const currentUid = firebase.auth().currentUser.uid;

  const userData = useSelector(state => state.user.userData);
  // const usersData = useSelector(state => state.users.usersData);
  const [initial, setInitial] = useState(true);
  const [chats, setChats] = useState([]);
  const [chatsLatestMsg, setChatsLatestMsg] = useState([]);
  const [usersData, setUsersData] = useState([]);

  // To listen for any update in Users collection
  // and then update usersData state
  useEffect(() => {
    const usersDataListener = firebase
      .firestore()
      .collection('users')
      .onSnapshot(querySnapshot => {
        let data = [];

        querySnapshot.forEach(doc => {
          if (doc.id !== currentUid) {
            data.push({ id: doc.id, ...doc.data() });
          }
        });

        setUsersData(data);
      });

    return () => usersDataListener();
  }, []);

  // To listen for any chat created for current user
  useEffect(() => {
    const chatsListener = firebase
      .firestore()
      .collection('users')
      .doc(firebase.auth().currentUser.uid)
      .onSnapshot(querySnapshot => {
        const latestChats = querySnapshot.data().chats;
        setChats(latestChats);
      });

    return () => chatsListener();
  }, []);

  // useEffect(() => {
  //   getUsers();
  // }, [chats]);

  // const getUsers = async () => {
  //   const querySnapshot = await firebase.firestore().collection('users').get();

  //   let temp_users = [];

  //   querySnapshot.forEach(doc => {
  //     if (currentUid !== doc.id) {
  //       temp_users.push({ id: doc.id, ...doc.data() });
  //     }
  //   });

  //   setUsersData(temp_users);
  // };

  return (
    <SafeAreaView style={styles.parentContainer}>
      <FlatList
        data={chats}
        renderItem={({ item }) => {
          let peer;
          peer = usersData.filter(data => data.chats.includes(item))[0];
          let latestChat =
            chatsLatestMsg.length > 0
              ? chatsLatestMsg.filter(data => data.chatId === item)[0]
              : {};

          // console.log('before condition', peer);

          // if (peer === undefined) {
          // firebase
          //   .firestore()
          //   .collection('users')
          //   .where('chats', 'array-contains', item)
          //   .get()
          //   .then(querySnapshot => {
          //     let data = [];

          //     querySnapshot.forEach(doc => {
          //       if (doc.id !== currentUid) {
          //         data.push({ id: doc.id, ...doc.data() });
          //       }
          //     });

          //     peer = data.filter(user => user.chats.includes(item))[0];

          //     console.log('undefined', peer);

          //     return (
          //       <ChatItem
          //         key={item}
          //         currentUid={userData.id}
          //         latestChat={latestChat}
          //         chatId={item}
          //         peer={peer}
          //         onPress={navigateChat}
          //       />
          //     );
          //   });
          // }

          console.log('!undefined', peer);

          return (
            <ChatItem
              key={item}
              currentUid={userData.id}
              latestChat={latestChat}
              chatId={item}
              peer={peer} // I keep getting undefined peer right here!
              onPress={navigateChat}
            />
          );
        }}
        keyExtractor={item => item}
        extraData={chats}
      />
    </SafeAreaView>
  );
};

最后,ChatItem:

const ChatItem = ({ peer, currentUid, chatId, onPress, latestChat }) => {
  let message = '',
    timestamp = '',
    id = '';

  if (latestChat.latestMessage !== undefined) {
    message = latestChat.latestMessage.message;
    timestamp = latestChat.latestMessage.timestamp;
    id = latestChat.latestMessage.id;
  }

  return (
    <Pressable
      style={styles.cardContainer}
      onPress={() =>
        onPress({
          peerData: peer,
          chatId: chatId,
          id: peer.id,
          name: peer.name,
          imagePath: peer.imagePath
        })
      }
    >
      <Layout style={styles.avatarContainer}>
        {peer.imagePath.length > 0 ? (
          <Image source={{ uri: peer.imagePath }} style={styles.avatar} />
        ) : (
          <UserAvatar name={peer.name} size={50} fontSize={22} />
        )}
      </Layout>
      <Layout style={styles.detailsContainer}>
        <Layout style={styles.topChatContainer}>
          <Layout style={styles.nameContainer}>
            <Text category='h6' style={styles.name}>
              {peer.name}
            </Text>
          </Layout>
          <Layout style={styles.timeContainer}>
            {timestamp.length > 0 && (
              <Text>{dayjs(timestamp).format('h:mm A')}</Text>
            )}
          </Layout>
        </Layout>
        <Layout style={styles.bottomChatContainer}>
          {message.length > 0 ? (
            <Text numberOfLines={1}>
              {currentUid === id ? `You: ${message}` : message}
            </Text>
          ) : (
            <Text>Click on here to start a conversation!</Text>
          )}
        </Layout>
      </Layout>
    </Pressable>
  );
};

推荐答案

如果我的眼睛不说谎,我找不到任何与 redux 相关的东西.您是否将您的功能组件连接到了 redux?

If my eyes do not lie, I cant find anything related to redux. Did you connect your functional component to redux?

一般来说,你也从 firestore 获取数据吗?只是确保

Also do you get the data from firestore in general? Just making sure

更新:如果您确实从 firestore 获取数据并且您在 redux 中有数据,请执行条件渲染.

UPDATE: If you do get the data from firestore and you have the data in redux the do the conditional rendering.

return(
     <>
    {
       chatData.length > 0 ?
       <FlatList .../> :
       <ActivityIndicator .../> // It is the spinner
    }
    </>

)

确保重新渲染屏幕.

这篇关于在 FlatList 的 renderItem 中执行 firestore 查询以传递数据以返回 Child的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆