Firestore文档与集合使用求助:单用户单文档存储贷款对象数组
Hey there! Let's get this sorted so each user has exactly one document storing all their loan objects in an array. Your current code is pulling multiple documents per user (since each loan is a separate doc), so we'll adjust both the data writing and data reading logic to match your desired structure.
Step 1: Adjust How You Add New Loans
Instead of creating a new document for each loan, you'll update a single user document (using their unique userId as the document ID) and append new loans to an array field. Use Firestore's arrayUnion to safely add items without duplicates (or manually push if you need duplicates):
// When adding a new loan (replace your existing "add document" code) const userDocRef = firebase.firestore().collection('goals').doc(userId); // Define your new loan object (example structure) const newLoan = { amount: 5000, createdAt: firebase.firestore.FieldValue.serverTimestamp(), // Add other loan fields here }; // Merge updates: creates the doc if it doesn't exist, adds the loan to the array userDocRef.set({ authorID: userId, loans: firebase.firestore.FieldValue.arrayUnion(newLoan) }, { merge: true });
Step 2: Rewrite the Data Fetching Logic
Your current code listens for multiple matching documents—we'll change this to listen for the single user document and extract the loans array directly:
const loansRef = firebase.firestore().collection('goals'); useEffect(() => { getPW(); let isMounted = true; const userDocRef = loansRef.doc(userId); // Target the user's unique doc // Subscribe to changes on the single user document const unsubscribe = userDocRef.onSnapshot( (docSnapshot) => { if (!isMounted) return; if (docSnapshot.exists()) { const userData = docSnapshot.data(); // Get the loans array (default to empty if it doesn't exist yet) const userLoans = userData.loans || []; setCourseGoals([...userLoans]); // Update state with the full array } else { // No document exists for this user yet—set empty array setCourseGoals([]); } }, (error) => { console.error('Error loading user loans:', error); } ); // Cleanup: stop listening when component unmounts return () => { isMounted = false; unsubscribe(); }; }, [userId]); // Re-run effect if userId changes
Key Changes Explained
- Single Document Target: We use
doc(userId)instead of awherequery to directly access the user's unique document (make sureuserIdis a stable unique ID, like the user's Firebase Auth UID). - Simpler State Update: No more looping through multiple docs—just extract the
loansarray from the single document. - Proper Cleanup: Added
unsubscribe()to stop the snapshot listener when the component unmounts, preventing memory leaks. - Dependency Array: Added
userIdto the effect dependencies so the listener updates if the user changes.
Notes to Keep in Mind
- Document Size Limit: Firestore documents have a 1MB size limit. If your users will have hundreds/thousands of loan objects, you might need to revert to the multi-document structure (but for most use cases, an array works great).
- Duplicates:
arrayUnionprevents duplicate entries. If you need to allow identical loan objects, you can instead fetch the current array, push the new item, and write it back (use a transaction if you need to handle concurrent updates safely).
内容的提问来源于stack exchange,提问作者cornOnDaJaCob04

