Skip to main content

Performing firestore query in renderItem of FlatList to pass data to return Child

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

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.

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.

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.

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. 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.

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

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.

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>
  );
};

And finally, the 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= 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>
  );
};
Via Active questions tagged javascript - Stack Overflow https://ift.tt/2FdjaAW

Comments

Popular posts from this blog

Why is my reports service not connecting?

I am trying to pull some data from a Postgres database using Node.js and node-postures but I can't figure out why my service isn't connecting. my routes/index.js file: const express = require('express'); const router = express.Router(); const ordersCountController = require('../controllers/ordersCountController'); const ordersController = require('../controllers/ordersController'); const weeklyReportsController = require('../controllers/weeklyReportsController'); router.get('/orders_count', ordersCountController); router.get('/orders', ordersController); router.get('/weekly_reports', weeklyReportsController); module.exports = router; My controllers/weeklyReportsController.js file: const weeklyReportsService = require('../services/weeklyReportsService'); const weeklyReportsController = async (req, res) => { try { const data = await weeklyReportsService; res.json({data}) console...

How to show number of registered users in Laravel based on usertype?

i'm trying to display data from the database in the admin dashboard i used this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count(); echo $users; ?> and i have successfully get the correct data from the database but what if i want to display a specific data for example in this user table there is "usertype" that specify if the user is normal user or admin i want to user the same code above but to display a specific usertype i tried this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count()->WHERE usertype =admin; echo $users; ?> but it didn't work, what am i doing wrong? source https://stackoverflow.com/questions/68199726/how-to-show-number-of-registered-users-in-laravel-based-on-usertype

The number of nodes and edges I calculated manually and by a method provided by networkx library dont match

I am trying to analyse a graph using networkx library in Python. I have implemented a function that returns the nodes and edges of that graph. After that I counted the number of nodes and edges by implementing the len() function for nodes and edges, which gave me 17 for both nodes and edges. However, when I used the method graph.number_of_nodes() of networkx library it gave me 53. My code: import pandas as pd import networkx as nx import matplotlib.pyplot as plt header_list = ["a","b","w"] E =pd.read_csv("aves-barn-swallow-contact-network.edges",sep=" ",header= None,names=header_list) # print(E.head()) # prints first few rows of the csv file G = nx.from_pandas_edgelist(E,"a","b",["w"]) nx.draw(G) plt.show() class GraphAnalyse: #finding nodes and edges def nodeEdge(self,Graph): nodes = Graph.nodes() edges = Graph.edges() ...