Austin Mueller
Austin Mueller

Reputation: 169

Firebase data structure & security

So im relatively new to using Firebase and im trying to figure out how to structure my data so that it is secure and normalized.

I need user based security for my data which in concept looks something like this:

{
    "users": {
        "simplelogin:1": {
            "email": "[email protected]",
            "id": "1",
            "name": "test",
            "provider": "password",
            "clients": {
                "client1": {
                    "name": "testClient",
                    "projects": {
                        "project1": {
                            "name": "testProject",
                            "sites": {
                                "site1": {
                                    "name": "testWobsite",
                                    "hits": {
                                        "hit1": {},
                                        "hit2": {},
                                        "hit3": {}
                                    }
                                },
                                "site2": {}
                            }
                        },
                        "project2": {}
                    }
                },
                "client2": {
                    "name": "test",
                    "projects": {}
                },
            }
        },
        "simplelogin:2": {
            "email": "[email protected]",
            "id": "2",
            "name": "test2",
            "provider": "password",
            "clients": {}
        }
    }
}

As you can see, the data structure here is extremely nested...
Users have clients, clients have projects, projects have sites, sites have hits...
So this is one of my main problems - im not entirely sure how to structure this data so that it isn't so nested.

The other issue im having is figuring out how to work the Firebase security rules.
In essence i want users to be able to create, update, and delete all data they own (clients, projects, sites, and hits)
Hits should be publicly writable, but only readable via the user who owns it.
Users should be able to register and log in, but not be able to read or write to any one else's data.

If anyone has any ideas about this or any tips or pointers, any advice would be greatly appreciated!
Thanks!

EDIT

Here's my attempt at normalizing the data... any thoughts..?

{
    "users": {
        "simplelogin:1": {
            "email": "[email protected]",
            "id": "1",
            "name": "test",
            "provider": "password",
            "clients": {
                "testClient": "client1",
                "test": "client2"
            }
        },
        "simplelogin:2": {
            "email": "[email protected]",
            "id": "2",
            "name": "test2",
            "provider": "password",
            "clients": {}
        }
    },
    "clients": {
        "client1": {
            "owner": "simplelogin:1",
            "parent": "",
            "name": "testClient",
            "projects": {
                "testProject": "project1",
                "testProject_2": "project2"
            }
        },
        "client2": {
            "owner": "simplelogin:1",
            "parent": "",
            "name": "test",
            "projects": {}
        }
    },
    "projects": {
        "project1": {
            "owner": "simplelogin:1",
            "parent": "client1",
            "name": "testProject",
            "sites": {
                "testWebsite": "site1",
                "testWebsite2": "site2"
            }
        },
        "project2": {
            "owner": "simplelogin:1",
            "parent": "client1",
            "name": "testProject_2",
            "sites": {}
        }
    },
    "sites": {
        "site1": {
            "owner": "simplelogin:1",
            "parent": "project1",
            "name": "testWebsite",
            "hits": {
                "firstHit": "hit1",
                "secondHit": "hit2",
                "thirdHit": "hit3"
            }
        },
        "site2": {
            "owner": "simplelogin:1",
            "parent": "project1",
            "name": "testWebsite2",
            "hits": {}
        }
    },
    "hits": {
        "hit1": {
            "owner": "simplelogin:1",
            "parent": "site1",
            "name": "firstHit"
        },
        "hit2": {
            "owner": "simplelogin:1",
            "parent": "site1",
            "name": "secondHit"
        },
        "hit3": {
            "owner": "simplelogin:1",
            "parent": "site1",
            "name": "thirdHit"
        }
    }
}

Upvotes: 0

Views: 974

Answers (1)

Leeft
Leeft

Reputation: 3837

You need to denormalize the data into several "tables", where the tables "link" to each other in some way. For example: each user would get a list of client_ids, each client would get a list of user_ids (assuming you're going to be accessing the data both ways). It is more data to keep in sync, but once it is a flat structure like that you'll also find it will be much easier to set your permissions.

This nested structure as you have it now is extremely inefficient with a NoSQL backend like Firebase since you have to retrieve all that data when you get the data for the user, and you have no way to tell e.g. which clients belong to which user without iterating through all of them.

Make sure to read https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html

Upvotes: 1

Related Questions