[英]Java, Firestore - Get multiple documents from firestore using an arraylist of document ids in android studio
[英]Trying to query multiple documents from Firestore in React at once, using an array from the users profile
这是我当前的代码:
useEffect(() => {
profile.familyCode.forEach((code) => {
console.log(code._id)
onSnapshot(query(collection(db, "group-posts", code._id, "posts"), orderBy("timestamp", "desc")
),
(querySnapshot) => {
const posts = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
setMessages([...messages, posts])
}
)
})
有两个 code._id's,目前它只是从其中一个设置我的消息。 我在这里错过了什么?
我尝试使用一些 firestores 逻辑表达式来做同样的事情但没有成功。 这样我至少可以拉出其中的一些,但我想从两个代码中拉出所有帖子。_id
您错过了setMessages
不会立即更新messages
本身的事实。 因此, messages
在这里使用旧的(或初始值)进行闭包捕获,并且调用setMessages
只会覆盖先前onSnapshot
之前设置的内容。
下一期 - onSnapshot
返回unsubscribe
函数,应该调用该函数来停止侦听器。 或者你会得到一些错误和内存泄漏。
这是一个可能的解决方案 custom hook
的快速编写(并没有真正测试过)的例子。
export function useProfileFamilyGroupPosts(profile) {
const [codeIds, setCodeIds] = useState([]);
const [messagesMap, setMessagesMap] = useState(new Map());
const messages = useMemo(() => {
if (!messagesMap || messagesMap.size === 0) return [];
// Note: might need some tweaks/fixes. Apply .flatMap if needed.
return Array.from(messagesMap).map(([k, v]) => v);
}, [messagesMap])
// extract codeIds only, some kind of optimization
useEffect(() => {
if (!profile?.familyCode) {
setCodeIds([]);
return;
}
const codes = profile.familyCode.map(x => x._id);
setCodeIds(curr => {
// primitive arrays comparison, replace if needed.
// if curr is same as codes array - return curr to prevent any future dependent useEffects executions
return curr.sort().toString() === codes.sort().toString() ? curr : codes;
})
}, [profile])
useEffect(() => {
if (!codeIds || codeIds.length === 0) {
setMessagesMap(new Map());
return;
}
const queries = codeIds.map(x => query(collection(db, "group-posts", x, "posts"), orderBy("timestamp", "desc")));
const unsubscribeFns = queries.map(x => {
return onSnapshot(x, (querySnapshot) => {
const posts = querySnapshot.docs.map((doc) => ({
id: doc.id,
...doc.data(),
}));
// update and re-set the Map object.
setMessagesMap(curr => {
curr.set(x, posts);
return new Map(curr)
})
});
});
// we need to unsubscribe to prevent memory leaks, etc
return () => {
unsubscribeFns.forEach(x => x());
// not sure if really needed
setMessagesMap(new Map());
}
}, [codeIds]);
return messages;
}
这个想法是用一个Map
(或只是{}
键值对象)来存储来自快照侦听器的数据,然后将该key-value
平铺到生成的messages
数组中。 并从钩子中返回这些消息。
用法将是
const messages = useProfileFamilyGroupPosts(profile);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.