How can I achieve this Many-to-many relationship in Firebase?

414 views Asked by At

I know Firebase does not support JOINs between nodes (like SQL Server does between tables), but that is exactly what I need to accomplish. Here's my situation:

I have a transactions node in Firebase like this (where I am including the category name for each transaction):

"transactions": 
{
    "-Jruazf35b9a_gAVmZBe": 
    {
    payee: "McDonalds", amount: "2.35", category: "Eating Out"
    }
    "-JruadR11b4a_aTVmZFi": 
    {
    payee: "Walmart", amount: "78.12", category: "Household"
    }
    "-Jruazf35b9a_AgvNWCq": 
    {
    payee: "CapitalOne", amount: "150.00", category: "Debt"
    }
    "-JryJF2c33ijbjbBc24p": 
    {
    payee: "FootLocker", amount: "107.54", category: "Personal Blow"
    }
    "-Jrz0T-aL61Vuw4SOqRb": 
    {
    payee: "Starbucks", amount: "2.88", category: "Eating Out"
    }
}

And I have a Categories node like this (where I am including the transactions under each category):

"categories": 
{
    "-Jruazf35b2a_gAVmZRy": 
    {
        categoryname: "Eating Out", 
        categorytype: "Expense"
    }
        "transactions": {
            "-Jruazf35b9a_AgvNWCq": {
                payee: "McDonalds", amount: "2.35"
               }
               .
               .
               .
        }
    }
}

So far so good. My data is flat. I'm able to show the list of transactions with the category name (screenshot below) and I can show the list of transactions under each category in the expenses per category section (screenshot not shown here).

enter image description here

The problem I have is that if I rename a category the change is only reflected for future transactions. Past transactions show the old category name.

This is obvious due to the way I'm saving the data. So my first logical reaction was to save the category unique ID in the transactions node instead of the category name. However, that presents the challenge where, in my SQL Server little brain, I would need a JOIN so I can get the list of transactions and also include the name of the category for each transaction.

How can I structure my data so that I can:

  1. show a list of transactions including the name of the category (as it does today)
  2. allow a user to rename a category and show the change reflected for ALL transactions (past and future)
  3. show a list of transactions under each category (I think the current approach would still be valid)
1

There are 1 answers

0
Frank van Puffelen On

Joining data from two lists is inherently a slow operation, especially on NoSQL databases.

I would recommend keeping the categoryName and adding a categoryId. That way you can show your current screen with a single read, but also link to the category. For how to deal with updating the categoryName in each transaction, see How to write denormalized data in Firebase and https://medium.com/@collardeau/es6-promises-with-firebase-76606f36c80c.

Alternatively: the list of categories is likely to be relatively small. So you could also pre-load it and perform a client-side lookup while you're iterating the transactions.