![](/img/trans.png)
[英]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.