使用Push插入数据后,如何查询Firebase中符合条件的数据?
It makes total sense to run into this issue—push() is perfect for generating unique, timestamp-ordered keys, but those keys don’t play nicely with filtering on custom fields like date across all your patient entries. Let’s break down why this happens and how to fix it.
Why Your Current Setup Isn’t Working
When you use push() to create entries under each patient ID (like 9876543210), those unique push keys are indexed by Firebase based on their own timestamp, not your date field. That means you can’t run a single query across all patients to pull entries where date='24/12/91'—you have to either query each patient’s entries individually or restructure your data for more efficient querying.
Solution 1: Query Each Patient’s Entries (Quick Fix for Small Datasets)
If you don’t have a huge number of patients, you can iterate over each patient ID and query their entries for the target date. First, add an index for the date field in your Firebase Realtime Database rules to avoid performance bottlenecks:
{ "rules": { "patient": { "$patientId": { ".indexOn": "date" } } } }
Then use this JavaScript example to fetch matching entries:
// First retrieve all patient IDs firebase.database().ref('patient').once('value') .then(patientSnapshot => { patientSnapshot.forEach(patientChild => { const patientId = patientChild.key; // Query this patient's entries for the target date return firebase.database().ref(`patient/${patientId}`) .orderByChild('date') .equalTo('24/12/91') .once('value') .then(entrySnapshot => { entrySnapshot.forEach(entryChild => { const entry = entryChild.val(); console.log(`Found entry for patient ${patientId}:`, entry); // Process your entry data here }); }); }); }) .catch(error => console.error('Error fetching data:', error));
This works but isn’t scalable for large patient lists—you’ll end up making multiple separate requests to Firebase.
Solution 2: Denormalize Your Data (Scalable, Recommended Approach)
Firebase is designed to work well with denormalized data for fast queries. Create a separate node that indexes entries by their date value. Whenever you add a new entry under patient/{patientId}/{pushKey}, also write a copy (or a reference) to entriesByDate/{date}/{pushKey}.
Your updated data structure would look like this:
- patient - 9876543210 - hjsfrhwugfshgjgjwwg - name: "..." - description: "..." - tokennumber: "..." - disease: "..." - date: "24/12/91" - entriesByDate - "24/12/91" - hjsfrhwugfshgjgjwwg - patientId: "9876543210" - name: "..." - description: "..." - tokennumber: "..." - disease: "..." - date: "24/12/91"
Now, querying all entries with the target date is a single, fast request:
firebase.database().ref('entriesByDate/24/12/91') .once('value') .then(snapshot => { snapshot.forEach(childSnapshot => { const entry = childSnapshot.val(); console.log('Matching entry:', entry); // Process your entry data here }); }) .catch(error => console.error('Error fetching data:', error));
This approach lets you quickly retrieve all matching entries without iterating over every patient, making it ideal for growing datasets. Just remember to keep both nodes in sync whenever you add, update, or delete an entry—use a transaction or batch update to ensure consistency across both locations.
内容的提问来源于stack exchange,提问作者Mohan

