'Firebase database query from multiple childs

I have some question regarding Firebase database structure. I am not familiar with it as I just started to learn it couple days ago. Basically 1 account can have many receipts, 1 receipt can have many items of different types, 1 receipt for 1 store and 1 receipt for 1 currency.

I have came up with the database design as below:

receipts {
    accountID1 : {
        receiptID1 : {
            date:
            store: {
                storeName: store1
                storeAddr: addr1
            }
            currency: {
                currencyName: currency1
                currentcySymbol: $
            }
            totalAmount: 50.00
        }
        receiptID2 : { ... }
    }
    accountID2 : { ... }
},
itemlists {
    receiptID1: {
        items: {
            itemID1 : {
                type: food
                name: snack
                price: 10.00
                quantity: 2
            }
            itemID2 : { ... } 
        }
    }
    receiptID2: { ... }
},
receiptIDsByStore {
    storeID1: {
        receiptID1: true
        receiptID2: true
    }
},
receiptIDsByCurrency {
    currencyID1: {
        receiptID1: true
        receiptID2: true
    }
},
stores {
    storeID1: {
        storeName: store1
        storeAddress: addr1
    }
},
currencies {
    currencyID1: {
        currencyName: currency1
        currencySymbol: $
    }
}   
itemIDsByType {
food: {
    itemID1: true,
    itemID2: true,
}
entertainment: {
    itemID3: true,
    itemID4: true,
}
}

So my question is:

  • Is there any redundancy mistake I made for the design above?

  • I can get the total amount of spend by each user from receipts, am I right? I can just query like receipts/accountID1 to get all the receipts then sum up the total amount.

  • How can I actually sum up the total spend by each user for each type of items? For instance, I wanted to find for food. So I query itemIDsByType/food, then get list of itemIDs, then from there query itemlists and check if receiptID is belonged to that particular account, it it is then get the unit price?

EDIT

receipts {
    accountID1 : {
        receiptID1 : {
            date : "07/07/2017"
            store : {
                storeName : "store1"
                storeAddr : "addr1"
            }
            currency : {
                currencyName : "currency1"
                currentcySymbol : "$"
            }
            totalAmount : "50.00"
            items : {
                itemID1 : true,
                itemID2 : true,
            }
        }
        receiptID2 : {
            date : "08/07/2017"
                store : {
                    storeName : "store1"
                    storeAddr : "addr1"
                }
                currency : {
                    currencyName : "currency1"
                    currentcySymbol : "$"
                }
                totalAmount : "20.00"
                items : {
                    itemID3 : true,
                    itemID4 : true,
                }
        }
    }
    
    accountID2 : { 
        receiptID3 : {
                date : "08/07/2017"
                    store : {
                        storeName : "store2"
                        storeAddr : "addr2"
                    }
                    currency : {
                        currencyName : "currency1"
                        currentcySymbol : "$"
                    }
                    totalAmount : "100.00"
                    items : {
                        itemID5 : true,
                        itemID6 : true,
                    }
            }
    }
},
items {
        itemID1 : {
            type : "food"
            name : "snack"
            unitprice : "10.00"
            quantity : "2"
        }
        itemID2 : { 
            type : "entertainment"
            name : "gaming equipment"
            unitprice : "150.00"
            quantity : "1"
        }
        itemID3 : { 
            type : "food"
            name : "fruit juice"
            unitprice : "4.00"
            quantity : "1"
        } 
        itemID4 : {
            type : "entertainment"
            name : "new year clothes"
            unitprice : "100.00"
            quantity : "1"
        }
        itemID5 : {
            type : "healthcare"
            name : "fever meds"
            unitprice : "100.00"
            quantity : "1"
        }
        itemID6 : {
            type : "healthcare"
            name : "flu meds"
            unitprice : "100.00"
            quantity : "1"
        }
},
receiptIDsByStore {
    storeID1 : {
        receiptID1 : true,
        receiptID2 : true,
    }
    storeID2 : {
        receiptID3 : true,
    }
},
receiptIDsByCurrency {
    currencyID1 : {
        receiptID1 : true,
        receiptID2 : true,
        receiptID3 : true,
    }
},
stores {
    storeID1 : {
        storeName : "store1"
        storeAddress : "addr1"
    }
    storeID2 : {
        storeName : "store2"
        storeAddress : "addr2"
    }
},
currencies {
    currencyID1 : {
        currencyName : "currency1"
        currencySymbol : "$"
    }
},
itemIDsByType {
    food : {
        itemID1 : true,
        itemID3 : true,
    }
    entertainment: {
        itemID2 : true,
        itemID4 : true,
    }
    healthcare : {
        itemID5 : true,
        itemID6 : true,
    }
}


Solution 1:[1]

Your database is very well structured. One thing you need to remeber when it comes to Firebase database structuring a is to have the data as flatten as possible and to make everything for the view. If you want to learn more about Firebase database structure i recomand you reading this posts: NOSQL DATA MODELING TECHNIQUES and Structuring your Firebase Data correctly for a Complex App.

Regarding your questions, as you you'll probably see in those posts, having the same data in different location is not a mistake, actually it's the opposite, it's ca ommon practice in Firebase. Yes, you can just query like receipts/accountID1 and get all the receipts. If you need a count, you can just simply use getChildrenCount() method directly on the DataSnapshot. Nested queries are not prohibited in Firebase. You can query once, to get those ids and second to get the desired data according to those ids.

Not at least, if you have a SQL background i recomand you watching this youtube tutorial sesries, The Firebase Database For SQL Developers.

Hope it helps.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alex Mamo