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:
- Accepting a chat request, updates
firestoreand then Redux store. Retrieve all users data from 'supposedly' updated Redux store. But it's undefined - Wrote a listener to listen for changes in the
userscollection infirestorebut it's 1 step slower when rendering the items in the FlatList and I get undefined sender's data - Wrote conditional checks to check if sender's data is undefined, if yes, perform a DIRECT
firestorequery to get the sender's data from theuserscollection. 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
Post a Comment