【发布时间】:2021-09-08 04:41:37
【问题描述】:
这是一个学校项目,我被一个 bug 卡住了超过 12 个小时...
上下文是用户接受来自发件人的聊天请求,然后,当我返回 聊天 选项卡时,会创建并显示一个新的聊天“房间”。所有这些都在TabNavigator 中完成。
我的预期结果是当我作为用户接受传入的聊天请求。
问题是我试图从firestore 获取发件人的数据,但我一直未定义它的数据。我对应用程序的初始加载从 firestore 获取所有用户数据并加载 Redux 存储。
流程:
发件人发送聊天请求 -> 更新 firestore 并且正在监听更改 -> 收件人看到一个新的聊天请求(这有效) -> 接受 -> 为发件人和收件人创建了新的聊天“房间”(应该自动显示)
我尝试不获取未定义发件人的方式:
- 接受聊天请求,更新
firestore,然后更新 Redux 存储。从“假定”更新的 Redux 存储中检索所有用户数据。但它是未定义的 - 编写了一个监听器来监听
firestore中users集合的变化,但在呈现 FlatList 中的项目时它会慢 1 步,并且我得到未定义的发件人数据 - 编写条件检查来检查发件人的数据是否未定义,如果是,则执行直接
firestore查询以从users集合中获取发件人的数据。但我仍然不确定。
我怀疑所有这些都是由于 FlatList 再次重新渲染,但我不确定如何控制它。
我确实在FlatList 中为道具extraData 指定了一个状态。
我已经用尽了所有可能的方法,做了所有的研究,我已经筋疲力尽了。
感谢您的帮助,非常感谢。
这里是ChatsOverviewScreen,清理了不必要的代码:
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>
);
};
【问题讨论】:
标签: javascript firebase react-native react-redux react-native-flatlist